Swift 3 Alamofire multipart upload

2019-01-21 21:27发布

Thanks to migration to Swift 3, I find it difficult to compile my project that uses Alamofire.

The problem occurs when uploading multipartFormData:

Alamofire.upload(.POST, URL, headers: headers, multipartFormData: {
        multipartFormData in
.
.
. 
}) 

Ambiguous reference to member 'upload(_:to:method:headers:)'

Any help much appreciated, thanks in advance!

RESOLVED:

 Alamofire.upload(multipartFormData: { (multipartFormData) in

        multipartFormData.append(fileData, withName: "file_pack", fileName: "file_pack", mimeType: "text/plain")


        for (key, value) in self.parameters {
            multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
        }
        }, with: URL2, encodingCompletion: { (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()
                    self.removeImage("frame", fileExtension: "txt")
                    if let JSON = response.result.value {
                        print("JSON: \(JSON)")
                    }
                }

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

    })

This is how upload method should be implemented in Swift 3

4条回答
劫难
2楼-- · 2019-01-21 22:07

For Swift 3 and Alamofire ~4.3.0

If someone like me tried to get request object synchronously (without using locks or dispatch_groups) you can use this approach:

// outer function
...
let string = "string to send"
let multipartFormData = MultipartFormData()
multipartFormData.append(string.data(using: .utf8)!, withName: "str")

guard let data = try? multipartFormData.encode() else {
    // fail appropriately
}

let request = sessionManager.upload(data,
                                    to: url,
                                    method: .post,
/* this is VERY IMPORTANT LINE */   headers: ["Content-Type" : multipartFormData.contentType])

request.validate()
// do whatever you need with request

Please note that you need to set Content-Type header from you multipartFormData as it contains boundaries.

If you don't need to have your request object synchronously the other answer with

Alamofire.upload(multipartFormData: { (multipartFormData) in

is working as expected. In case of successful encoding of data it will return you request object in callback closure.

IMPORTANT NOTE: if you use the method I have described, it will block your thread (in most cases you probably are in Main thread) to copy and encode your data. So don't use it for large files or whatever. It is async in Alamofire on purpose.

查看更多
我想做一个坏孩纸
3楼-- · 2019-01-21 22:19

In swift 3, trying to set multipartFormData as @DCDC pointed out in his solution. XCode try to cast to AnyObject before .data(), so instead of

value.data(using: String.Encoding.utf8)!, withName: key

I did

[replace_your_var_name_here].data(using: String.Encoding.utf8)!, withName: key

In my case my var list was not big so hardcoding was an option.

查看更多
Fickle 薄情
4楼-- · 2019-01-21 22:23

For example, using Alamofire 4.0.0 in Swift 3:

(make sure you are 4.0.0 ready as it looks like you haven't updated your Alamofire yet)

Alamofire.upload(multipartFormData: { (multipartFormData) in
        // code
    }, to: URL, encodingCompletion: { (result) in
        // code
    })

or

Alamofire.upload(multipartFormData: { (multipartFormData) in
        // code
    }, with: URL, encodingCompletion: { (result) in
        // code
    })

So headers need to be passed by URL request:

let URL = try! URLRequest(url: "http://example.com", method: .get, headers: headers)
查看更多
仙女界的扛把子
5楼-- · 2019-01-21 22:24

Try this one and url set as @pedrouan said.

Alamofire.upload(multipartFormData: { (multipartFormData) in
       multipartFormData.append(imageData, withName: "xyz", fileName: "file.jpeg", mimeType: "image/jpeg")
}, to: url) 
{ (result) in
      //result
}
查看更多
登录 后发表回答