使用 Swift 3 和 Alamofire 上传文件

Posted

技术标签:

【中文标题】使用 Swift 3 和 Alamofire 上传文件【英文标题】:Uploading a file with Swift 3 and Alamofire 【发布时间】:2017-05-08 15:41:09 【问题描述】:

我很难获得正确的 Alamofire 语法来上传文件。服务器接口是一个 Rest API。我需要传递许多参数来访问正确的数据库和特定记录。 示例:

"https://ram23jtog.tt.rp.com/ewws/EWUpdate/.json?$KB=ITIL&$table=asset_table&$login=testuser2&$password=pwd123&$lang=en&id=18005&tdd_form=2017-5-8-911-6633442.pdf"

关于参数需要注意的一点是,“ID”参数需要放在末尾,以便首先读取表和登录信息 - 否则就会出现。

我已尝试加载参数,然后再追加:

        let parameters: Parameters = [

            "&tdd_form" : "test",
            "&id"       : "\(self.inventoryDeviceVal.recId!)",
            "$lang"     : "en",
            "$password" : "\(self.sharedDataVal.appUserPassword!)",
            "$login"    : "\(self.sharedDataVal.appUserID!)",
            "$table"    : "asset_table",
            "$KB"       : "ITIL"

        ]

        for (key, value) in parameters 
                    multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
        

在我看来,参数被截断或出现错误,导致其中一些参数无法加载。

Alamofire 请求:

        Alamofire.upload(
            multipartFormData:  multipartFormData in


                for (key, value) in parameters 
                    multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
                

                multipartFormData.append(fileURL, withName: fileName, fileName: fileName, mimeType: "application/pdf")

            , to: updateCriteria)  (result) in

                    switch result 

                    case .success(let upload, _, _):
                        upload.responseJSON  response in
                            //self.delegate?.showSuccessAlert()
                            print(response.request!)  // original URL request
                            print(response.response!) // URL response
                            print(response.data!)     // server data
                            print(response.result)   // result of response serialization
                            //                        self.showSuccesAlert()

                            if let JSON = response.result.value 
                            print("JSON: \(JSON)")
                            
                        

                    case .failure(let encodingError):
                        //self.delegate?.showFailAlert()
                        print(encodingError)
                

            


    

有什么建议吗?做一个简单的 Alamofire 请求会比分段上传更容易吗?

分辨率

根据 Musa 的建议重新配置我的参数:

  let parameters = [
        [
            "name"  : "$KB",
            "value" : "ITIL"
        ],
        [
            "name"  : "$table",
            "value" : "asset_table"
        ],
        [
            "name"  : "$login",
            "value" : "\(self.sharedDataVal.appUserID!)"
        ],
        [
            "name"  : "$password",
            "value" : "\(self.sharedDataVal.appUserPassword!)"
        ],
        [
            "name"  : "$lang",
            "value" : "en"
        ],
        [
            "name"  : "id",
            "value" : "\(self.inventoryDeviceVal.recId!)"
        ]

    ]

我在参数定义中添加了参数“tdd_form”。我调整了追加,以便在正确传递参数的情况下使用右侧部分中的“tdd_form”参数正确编码。

        Alamofire.upload(
            multipartFormData:  multipartFormData in


                for param in parameters  
                    multipartFormData.append((param["value"]?.data(using: .utf8)!)!, withName: param["name"]!)
                

                multipartFormData.append(fileURL, withName: "tdd_form", fileName: fileName, mimeType: "application/pdf")

            , to: updateCriteria)  (result) in

                    switch result 

                    case .success(let upload, _, _):
                        upload.responseJSON  response in
                            //self.delegate?.showSuccessAlert()
                            print(response.request!)  // original URL request
                            print(response.response!) // URL response
                            print(response.data!)     // server data
                            print(response.result)   // result of response serialization
                            //                        self.showSuccesAlert()

                            if let JSON = response.result.value 
                            print("JSON: \(JSON)")
                            
                        

                    case .failure(let encodingError):
                        //self.delegate?.showFailAlert()
                        print(encodingError)
                

            

完美运行!!

【问题讨论】:

就我个人而言,我无法让 URL 查询参数与 MultipartFormData 一起使用,所以我不太确定。我在我的应用程序中解决它的方法是自己使用查询参数构建 URL,然后只将文件附加到 MultipartFormData 并上传到该 URL。示例:multipartFormData.append(file, withName: "file") 然后upload 方法上的to: 参数为to: "\(url)?email=\(email)&type=\(type)",但将查询参数替换为您需要的参数。 【参考方案1】:

我遇到了同样的问题,我就是这样解决的

    var parameters = [
        [
            "name": "tdd_form",
            "value": "test"
        ],
        [
            "name": "id",
            "value": "\(self.inventoryDeviceVal.recId!)"
        ]
          .
          .
          .
         etc
    ]

    Alamofire.upload(
        multipartFormData:  multipartFormData in

            //convert parameters to data
            for param in parameters 
                multipartFormData.append((param["value"]?.data(using: .utf8)!)!, withName: param["name"]!)
            

            //Add the data

            //Mine was image , this is how I did it
            //let uuid = UUID().uuidString.lowercased()
            //multipartFormData.append(imgData, withName: "images[]", fileName: "\(uuid).jpg", mimeType: "image/jpeg")

            multipartFormData.append(fileURL, withName: fileName, fileName: fileName, mimeType: "application/pdf")
    ,
        to: updateCriteria) (result) in

            switch result 

            case .success(let upload, _, _):
                upload.responseJSON  response in
                    //self.delegate?.showSuccessAlert()
                    print(response.request!)  // original URL request
                    print(response.response!) // URL response
                    print(response.data!)     // server data
                    print(response.result)   // result of response serialization
                    //                        self.showSuccesAlert()

                    if let JSON = response.result.value 
                        print("JSON: \(JSON)")
                    
                

            case .failure(let encodingError):
                //self.delegate?.showFailAlert()
                print(encodingError)
            

    

【讨论】:

Musa,您设置参数的方式绝对正确。我不得不为自己的目的调整其中的一些参数,但这让我走上了正确的道路。已经为此工作了数周。我将发布我的更改,以便所有人都能看到。

以上是关于使用 Swift 3 和 Alamofire 上传文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Alamofire 4 swift 3 上传图像

text Alamofire - 使用Swift 3上传文件

Swift 3 使用 Alamofire 将数据上传到服务器

使用 Alamofire Swift 3 上传图像 (Base64)

Alamofire(Swift 3):对成员“上传(..”)的模糊引用

Alamofire 4 swift 3 上传带有标题的 MultipartFormData 未发布