I'm trying to upload a image with other parameters the issue occurs when my one of my parameters are a datatype of Array<String>. The array is empty on the server side.:/
self.manager.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: imgKey, fileName: "image.jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
},
to: path,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint("SUCCESS RESPONSE: \(response)")
}
case .failure(let encodingError):
print("ERROR RESPONSE: \(encodingError)")
}
}
)
The datatype of my parameters are [String : Any]
What I'm exactly doing wrong? :(
the same here plz need to fix it
Also having this issue, just after I updated to the most recent iOS 10.1
The type of my params are [String : String]
the same issue is faced by me Please help
@BilalReffas
I solved the issue by setting time out for request using SessionManager
`
//Class variable
var alamoManager: SessionManager?
//viewdidload or in viewwillappear
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
alamoManager = Alamofire.SessionManager(configuration: configuration)
//In your method
self.alamoManager.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: imgKey, fileName: "image.jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append(String(describing: value).data(using: .utf8)!, withName: key)
}
},
to: path,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response.response?.statusCode)
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
print(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
print(self.response)
}
}
)`
@yadavanand it's not working for me
I've got it working now. For me, turns out it was something pretty stupid, but perhaps it will help someone here anyway:
In Swift 2.2 NSURL.path returns the entire URL. In Swift 3 however URL.path returns only the file path and not the entire URL. Since all Alamofire functions take an URL as argument this is mostly not a problem, but for this scenario it is, since it takes a string.
So for http://www.yoursite.com/api/dosomething.php
Swift 2.2 NSURL.path returns http://www.yoursite.com/api/dosomething.php
Swift 3 URL.path returns /api/dosomething.php
Replacing URL.path with URL.absoluteString resolved it for me.
@guidove thank you maybe it will help other people in the community.:)
Anyway it's still not working for me. :/
I've got the same problem and couldn't find a solution for Alamofire 4
I just realized that the order is important:
for (key, value) in parameters {
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")
works. Whereas
multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
won't work. Is this expected behaviour?
Not working for me. Does is working for you @LucidityDesign ?
Here's my full and working (Swift 3 / Alamofire 4) code. Few global variables in there but you get the point i guess.
func uploadImage(_ imageFileName: String) {
if let imageData = try? Data(contentsOf: localFolder.images.appendingPathComponent(imageFileName)) {
let parameters = ["imageFileName":imageFileName, "userID":UD.userID!]
let URL = serverURL.appendingPathComponent("image_upload.php")
Alamofire.upload(multipartFormData: {
multipartFormData in
multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to: URL.absoluteString, method: .post
,encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseString { response in
switch response.result {
case .failure(let err):
printError("image upload failed: \(err)")
break
case .success(let str):
if str == "error" {
printError("image upload failed. check server logs")
}
else {
print("image upload successfull")
}
}
}
case .failure(let encodingError):
print(encodingError)
}
})
}
}
My php server code echo's a string "OK" or "Error"
@guidove your example works only if your parameters are a type of Array<String>
@BilalReffas OK. Perhaps something to do with the parameter encoding you can add as a variable to the normal Alamofire.request methods? Have you tried JSONenconding your parameter values inside the for loop (as a first line, so before the .append?) Just a hunch as I didn't need to do this myself.
Also... just to be sure. You are saying <String>Array, but I'm guessing you mean Array<String> or in another notation [String], right? So, your parameter declaration would be something like this:
let params = ["key1":["string1", "string2", "string3"]], correct? If not, can you show us the code where you declare your params?
You should not use this for creating the data representation: String(describing: value).data(using: .utf8)!. The problem with that is, that it's just printing a debug representation of the object and transforms that String to Data. What you really need (in case of the [String] argument is using JSONSerialization instead of printing the object.
I would suggest introducing a serializer which gives you an appropriate data representation like this:
enum DataSerializer {
static func serialize(_ value: Any) -> Data? {
if JSONSerialization.isValidJSONObject(value) {
return try? JSONSerialization.data(withJSONObject: value, options: [])
}
else {
return String(describing: value).data(using: .utf8)
}
}
}
You could then check if the data could be serialised and if, set it in the request parameters.
I am really excited, if that fixes your problem :)
@guidove Yes I mean Array<String> :) let params:[String: Any] = ["text":text, "[friend_ids":friend_ids] This is how my params declaration look's like friend_ids is a type of [String]
Thank you everyone for helping each other out here. In the future I'd suggest moving this type of question to Stack Overflow. I'm going to go ahead and close it out for now since there's no actionable Alamofire issue here.
Please feel free to continue your investigation here.
Cheers. 馃嵒
I'm done with this, the issue is not in this line
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
just change your .put method to .post 馃憤
let URL = try! URLRequest(url: 'http://your.url' , method: .post, headers: your_headers
It's working!