Swift 3 Alamofire multipart upload
Solution 1
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)
Solution 2
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
}
Solution 3
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.
Solution 4
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.
Related videos on Youtube
Comments
-
theDC about 4 years
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
-
Eric Aya over 7 yearsThe method signatures have changed. Comment your existing ones and let Xcode's autocomplete guide you for writing the new ones.
-
Sahil over 7 yearsand you can also go to alamofire on gitub. github.com/Alamofire/Alamofire
-
-
theDC over 7 yearsone more question, what code should go in first placeholder(multipartFormData in) and what should go in the latter (result in)? Formerly there was only one closure
-
pedrouan over 7 yearsIt is not mandatory to fill it with code, closures are for you eventual use. But I guess, completion closures are useful as you get feedback since it's asynchronous method.
-
theDC over 7 yearsLet us continue this discussion in chat.
-
pedrouan over 7 years@DCDC It looks like your Alamofire has not been updated to 4.0.0
-
theDC over 7 yearsWell it is, otherwise it would nit show the first error message I guess
-
pedrouan over 7 yearsYes -and, if you want to migrate to Swift 3.0, upgrading Alamofire to 4 version is a must. Now I guess you would get that by yourself, if it is from 4. Anyway, if you need some assistance and/or create another question any time, comment me and I'll check it.
-
theDC over 7 yearsOk, it doesn't return any errors now, the problem was with my method implementation, see my edited question. Thanks!
-
Gregg over 7 yearsThis still doesn't work for me..... anybody else? Not sure what else to do.
-
Saeid over 7 yearshow about audio file? - i try to send a audio file in this form : multipartFormData.append(audioLocalPath, withName: "file", fileName: "file", mimeType: "application/octet-stream") but occur this error : multipartEncodingFailed(Alamofire.AFError.MultipartEncodingFailureReason.bodyPartFileNotReachableWithError(file:///var/mobile/Containers/....... /Documents/item.mp3, NSUnderlyingError=0x16049100 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}})) - where is problem? -bad request or bad audio path?
-
Bilawal Liaqat about 7 years@pedrouan Thank you man . I was looking for this from last 5 hours. and there was many solution available but this one work only
-
Arbitur almost 7 yearsWhere is
sessionManager
comming from? -
user1264176 almost 7 years@Arbitur it is an instance of Alamofire.SessionManager you use to make a request. In my production code it is created once when app is initialised and used throughout the app. In this particular snippet from the answer it can be created in the code marked as '...' after //outer function. Although again, it is not relevant where you have created your session manager for this snippet.
-
Aashish over 6 yearsusing the urlRequest gives error <"Type of expression is ambiguous without more content" >, but works if only used url. What am i missing??