首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用REDCap将文件从iOS设备上传到

如何使用REDCap将文件从iOS设备上传到
EN

Stack Overflow用户
提问于 2021-12-29 19:18:11
回答 1查看 77关注 0票数 0

我正在尝试将保存到应用程序(使用ResearchKit构建的)目录中的文件上传到服务器(通过REDCap API)。REDCap API游乐场建议使用几种语言编写代码,但不是Obj或Swift。在这种情况下,我需要使用Swift,这对我来说是第一次。下面是我尝试的一种方法,遗憾的是,这种方法不起作用:

代码语言:javascript
复制
func postFileToRedcap (_ fileUrl: URL) {
    guard let url = URL (string: "https://our_redcap_url.edu/api/") else {return}
    let token = "ABCDEFGHIJK123456789" // unique to REDCap project
    let record = "1" // can be set elsewhere
    let event = ""
    let field = "file_upload_field" // name of field in REDCap
    
    if !fileUrl.pathComponents.isEmpty {
        let fileName = URL(fileURLWithPath: fileUrl.absoluteString).lastPathComponent
        var request = URLRequest.init(url: url)
        request.httpMethod = "POST"
        // parameters required by REDCap
        request.addValue(token, forHTTPHeaderField: "token")
        request.addValue(fileName, forHTTPHeaderField: "content")
        request.addValue("import", forHTTPHeaderField: "action")
        request.addValue(record, forHTTPHeaderField: "record")
        request.addValue(field, forHTTPHeaderField: "field")
        request.addValue(event, forHTTPHeaderField: "event")
        request.addValue("json", forHTTPHeaderField: "returnFormat")
        
        let task = URLSession.shared.uploadTask(
            with: request,
            fromFile: fileUrl
        )
        task.resume()
    }
}

主要问题似乎是参数设置,但我似乎找不到适用于REDCap的解决方案。

所有的帮助都受到了亲切的欢迎。提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-28 09:27:27

经过了太多的时间,我意识到关键是使用

request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

但是是Postman的代码片段使我能够成功地构建参数数组和有效载荷。我敢肯定,这是一个可以简化的工作版本。

代码语言:javascript
复制
   import Foundation
     
    guard let url = URL (string: "https://our_redcap_url.edu/api/") else {return}
    let token = "ABCDEFGHIJK123456789" // unique to REDCap project
    let record : = "1" // set elsewhere
    let event = ""
    let field = "file_upload_field" // name of field in REDCap
    let path = "path_of_file_to_be_uploaded"
    let repeat_instance : Int = 1
     
    let parameters = [
        [
        "key": "token",
        "value": token,
        "type": "text"
        ],
        [
        "key": "content",
        "value": "file",
        "type": "text"
        ],
        [
        "key": "action",
        "value": "import",
        "type": "text"
        ],
        [
        "key": "record",
        "value": record,
        "type": "text"
        ],
        [
        "key": "field",
        "value": field_name,
        "type": "text"
        ],
        [
        "key": "event",
        "value": event,
        "type": "text"
        ],
        [
        "key": "repeat_instance",
        "value": repeat_instance,
        "type": "text"
        ],
        [
        "key": "returnFormat",
        "value": "json",
        "type": "text"
        ],
        [
        "key": "file",
        "src": path,
        "type": "file"
        ]] as [[String : Any]]
     
    // build payload
    let boundary = "Boundary-\(UUID().uuidString)"
    var body = ""
    for param in parameters {
    if param["disabled"] == nil {
        let paramName = param["key"]!
        body += "--\(boundary)\r\n"
        body += "Content-Disposition:form-data; name=\"\(paramName)\""
        if param["contentType"] != nil {
            body += "\r\nContent-Type: \(param["contentType"] as! String)"
        }
        let paramType = param["type"] as! String
        if paramType == "text" {
            let paramValue = param["value"] as! String
            body += "\r\n\r\n\(paramValue)\r\n"
        } else {
            let paramSrc = param["src"] as! String
            let fileData = try? NSData(contentsOfFile:paramSrc, options:[]) as Data
            let fileContent = String(data: fileData!, encoding: .utf8)!
            body += "; filename=\"\(paramSrc)\"\r\n"
            + "Content-Type: \"content-type header\"\r\n\r\n\(fileContent)\r\n"
            }
        }
    }
    body += "--\(boundary)--\r\n";
    let postData = body.data(using: .utf8)
     
    // create URL request and session
    var request = URLRequest(url: url,timeoutInterval: Double.infinity)
    request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
     
    request.httpMethod = "POST"
    request.httpBody = postData
     
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data else {
        print(String(describing: error))
        return
        }
        print(String(data: data, encoding: .utf8)!)
    }
    task.resume()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70524003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档