Sending Custom Object as form-data in Alamofire - ios

I have an endpoint in Java to upload a file on my server. It accepts MultipartFile and an Info object in form-data.
#PostMapping(path = "/mobile/upload", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public HttpEntity<String> fileUpload(#RequestPart Info fileInfo, #RequestPart MultipartFile file, #RequestHeader("x-auth") String token){}
Using Alamofire my first approach was this but I was getting 415 error, probably because the way I was sending fileInfo was not correct. I made sure of this by commenting the Info object from server side and then tried sending the file alone and it was a success.
func uploadDocument(fileUrl: URL, fileInfo: Info, authKey: String) {
let headers: HTTPHeaders = [ "x-auth": authKey ]
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(fileUrl, withName: "file")
multipartFormData.append(fileInfo, withName: "fileInfo")
}, to: "my_url", method: .post,headers: headers)
.responseDecodable(of: UploadResponse.self) { response in }
}
Then I tried encoding my fileInfo object, again 415 error code.
let jsonObj = (try? JSONEncoder().encode(fileInfo))!
//
multipartFormData.append(jsonObj, withName: "fileInfo")
Also tried but getting exception 'NSInvalidArgumentException'
multipartFormData.append(((fileInfo as AnyObject).data(using: String.Encoding.utf8.rawValue))!, withName: "fileInfo")
How can I send this object in Alamofire ?
I am able to perform the request in Postman with 200.

Related

windows server returns 404 when tried to request POST using Alamofire (swift)

I am trying to post a json object to my windows server but it returns 404 each time. I'm using the Alamofire library since it's really convenient to use. The server returns 200 (ok) when i try to use the get method and when i send my post request to "https://httpbin.org/post" to test my code. I'm guessing there is something wrong with the server side but i can't figure out what.
Here is my client side code, in case something is wrong with it:
let urlSend = "http://171.217.5.232:1015/post"
let params = [
"Action": "sendCode",
"Email": enteredEmail,
"Code": code
]
AF.request(urlSend, method: .post, parameters: params, encoder: JSONParameterEncoder.default).responseJSON { response in
debugPrint(response)
}
You can use Alamofire.upload and this is going to work
Alamofire.upload(multipartFormData: { (MultipartFormData) in
for (key, value) in params {
if let data = value.data(using: .utf8) {
MultipartFormData.append(data, withName: key)
}
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: header) { (results) in
}

Alamofire 5 - Ambiguous reference to member 'upload(multipartFormData:to:usingThreshold:method:headers:interceptor:fileManager:)'

AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(data, withName: "Image")
}, to: url, usingThreshold: UInt64.init(), method: .post, headers: httpHeaders, interceptor: nil, fileManager: .default)
And I'm getting this error:
"Ambiguous reference to member 'upload(multipartFormData:to:usingThreshold:method:headers:interceptor:fileManager:)'"
Most likely this is actually a problem with one of your parameters. Most often this is due to a type mismatch. Your most likely culprit is the httpHeaders value, as Alamofire 5 (which you appear to be using) uses a new HTTPHeaders type, rather than [String: String]. Updating your headers to use that type may fix the issue.
Additionally, you don't need to pass most of those parameters anyway. Calling just:
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(data, withName: "Image")
}, to: url, headers: httpHeaders)
does the same thing.

Pass JSON object in GET request: iOS

I want to add the JSON object in GET request with URL. Please refer below URL.
https://testdata.com/xyz/&form={"id":"12", "data": "3"}
I am getting nil while converting String to URL
let serviceUrl = URL(string: url)
Thanks in advance.
I was already tried below solution but unfortunately no luck.
JSONSerialization.data
converting to string with utf8
removed whitespaces if any
addingPercentEncoding with URL host allowed
It's not recommended, to send a request body with GET request. GET request means to fetch all the resources/content that this URL has to offer. If they are parsing the GET body on server side, it's against the semantics. But if you really need to do it. Use Almofire. Here's a Sample Code.
let parameters : [String : Any] = [
"id":"12",
"data":"3"
]
func getContent(parameters: [String: Any]) {
Alamofire.request("http://18.218.235.193:3000/user/securedtoken", method:
.get, parameters: parameters, encoding: JSONEncoding.default)
.responseObject {(response:
DataResponse<YOUR RESPONSE MODEL HERE>) in
let response = response.result.value
//Do Something (Success)
}
}
I recommend you to use Alamofire library. You can do what you want using following code snippet
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["form": ["id": 12, "data": 3]])
.response { request, response, data, error in
print(request)
print(response)
print(error)
}

IOS Swift Alamofire JSON Request

I am trying to make a JSON Request with Alamofire but the response is in Greek and Swift returns:
Response
{
id = 4;
name = "\U0395\U03bb\U03b1\U03b9\U03cc\U03bb\U03b1\U03b4\U03bf"
url = "http://www.gaiaskarpos.com/app/images/categories/olive.png";
}
The problem is at name field.
//Swift Alamofire Request
Alamofire.request(.GET, "http://gaiaskarpos.com/applegetCategores.php",
encoding:.JSON).validate().responseJSON{(response)->
Void in print("Response Json : \(response.result.value)")
I had a same issue in Arabic/Persian chars and It's my solution:
json variable :
{
message = "\U062f\U0633\U062a\U06af\U0627\U0647 \U0645\U0639\U062a\U0628\U0631 \U0646\U06cc\U0633\U062a";
status = 0;
}
So I casted json to [String: AnyObject] :
var test = json as? [String : AnyObject]
print(test)
It's fixed. You should give it a try.
Why is your encoding .JSON? You send .GET-request and you don't need to specify the type of encoding in your request.
Alamofire documentation say:
Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
So use it. Links -> http://cocoadocs.org/docsets/Alamofire/1.1.3/ and https://github.com/Alamofire/Alamofire
You must specify the type of encoding when you pass parameters in the body of your request. It is for .POST and .PUT requests.
Try to print 'name' to Debug area. Maybe you'll get name in normal encoding... Xcode has the disadvantage: it shows not-UTF8 data in response like '\U0395\U03bb ... ... ... \U03b1\U03b9\' when there is some level of nested data in response.
Try to use NSUTF8StringEncoding with alamofire response
encoding: NSUTF8StringEncoding
Try to serialize the JSON with below code this might help you
let dict = NSJSONSerialization.JSONObjectWithData(jsonString.dataUsingEncoding(NSUTF8StringEncoding)!,
options: nil, error: nil) as [String : String]

Alamofire invalid value around character 0

Alamofire.request(.GET, "url").authenticate(user: "", password: "").responseJSON() {
(request, response, json, error) in
println(error)
println(json)
}
This is my request with Alamofire, for a certain request it sometime works, but sometimes i get:
Optional(Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Invalid value around character 0.) UserInfo=0x78e74b80 {NSDebugDescription=Invalid value around character 0.})
I've read that this can be due to invalid JSON, but the response is a static json string that i have validated in JSON validator as valid. It does contain å ä ö characters and some HTML.
Why am i getting this error sometimes?
I also faced same issue. I tried responseString instead of responseJSON and it worked. I guess this is a bug in Alamofire with using it with django.
In my case , my server URL was incorrect. Check your server URL !!
I got same error while uploading image in multipart form in Alamofire as i was using
multipartFormData.appendBodyPart(data: image1Data, name: "file")
i fixed by replacing by
multipartFormData.appendBodyPart(data: image1Data, name: "file", fileName: "myImage.png", mimeType: "image/png")
Hope this help someone.
May this Help YOu
Alamofire.request(.GET, "YOUR_URL")
.validate()
.responseString { response in
print("Success: \(response.result.isSuccess)")
print("Response String: \(response.result.value)")
}
The same issue happened to me and it actually ended up being a server issue since the content type wasn't set.
Adding
.validate(contentType: ["application/json"])
To the request chain solved it for me
Alamofire.request(.GET, "url")
.validate(contentType: ["application/json"])
.authenticate(user: "", password: "")
.responseJSON() { response in
switch response.result {
case .Success:
print("It worked!")
print(response.result.value)
case .Failure(let error):
print(error)
}
}
I got the same error. But i found the solution for it.
NOTE 1: "It is not Alarmofire error", it's bcouse of server error.
NOTE 2: You don't need to change "responseJSON" to "responseString".
public func fetchDataFromServerUsingXWWWFormUrlencoded(parameter:NSDictionary, completionHandler: #escaping (_ result:NSDictionary) -> Void) -> Void {
let headers = ["Content-Type": "application/x-www-form-urlencoded"]
let completeURL = "http://the_complete_url_here"
Alamofire.request(completeURL, method: .post, parameters: (parameter as! Parameters), encoding: URLEncoding.default, headers: headers).responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)") // your JSONResponse result
completionHandler(JSON as! NSDictionary)
}
else {
print(response.result.error!)
}
}
}
This is how I managed to resolve the Invalid 3840 Err.
The error log
responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
It was with Encoding Type used in the Request, The Encoding Type used should be acceptedin your Server-Side.
In-order to know the Encoding I had to run through all the Encoding Types:
default/
methodDependent/
queryString/
httpBody
let headers: HTTPHeaders = [
"Authorization": "Info XXX",
"Accept": "application/json",
"Content-Type" :"application/json"
]
let parameters:Parameters = [
"items": [
"item1" : value,
"item2": value,
"item3" : value
]
]
Alamofire.request("URL",method: .post, parameters: parameters,encoding:URLEncoding.queryString, headers: headers).responseJSON { response in
debugPrint(response)
}
It also depends upon the response we are recieving use the appropriate
responseString
responseJSON
responseData
If the response is not a JSON & just string in response use responseString
Example: in-case of login/ create token API :
"20dsoqs0287349y4ka85u6f24gmr6pah"
responseString
I solved using this as header:
let header = ["Content-Type": "application/json",
"accept": "application/json"]
In my case, there was an extra / in the URL .
Maybe it is too late but I solved this problem in another way not mentioned here:
When you use .responseJSON(), you must set the response header with content-type = application/json, if not, it'll crash even if your body is a valid JSON. So, maybe your response header are empty or using another content-type.
Make sure your response header is set with content-type = application/json to .responseJSON() in Alamofire work properly.
Hey guys this is what I found to be my issue: I was calling Alamofire via a function to Authenticate Users: I used the function "Login User" With the parameters that would be called from the "body"(email: String, password: String) That would be passed
my errr was exactly:
optional(alamofire.aferror.responseserializationfailed(alamofire.aferror.responseserializationfailurereason.jsonserializationfailed(error domain=nscocoaerrordomain code=3840 "invalid value around character 0." userinfo={nsdebugdescription=invalid value around character 0
character 0 is the key here: meaning the the call for the "email" was not matching the parameters: See the code below
func loginUser(email: String, password: String, completed: #escaping downloadComplete) {
let lowerCasedEmail = email.lowercased()
let header = [
"Content-Type" : "application/json; charset=utf-8"
]
let body: [String: Any] = [
"email": lowerCasedEmail,
"password": password
]
Alamofire.request(LOGIN_USER, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
if response.result.error == nil {
if let data = response.result.value as? Dictionary<String, AnyObject> {
if let email = data["user"] as? String {
self.userEmail = email
print(self.userEmail)
}
if let token = data["token"] as? String {
self.token_Key = token
print(self.token_Key)
}
"email" in function parameters must match the let "email" when parsing then it will work..I no longer got the error...And character 0 was the "email" in the "body" parameter for the Alamofire request:
Hope this helps
I was sending the improper type (String) to the server in my parameters (needed to be an Int).
Error was resolved after adding encoding: JSONEncoding.default with Alamofire.
Alamofire.request(urlString, method: .post, parameters:
parameters,encoding:
JSONEncoding.default, headers: nil).responseJSON {
response in
switch response.result {
case .success:
print(response)
break
case .failure(let error):
print(error)
}
}
The application I was working on this morning had the same error. I believed it to be a server side error since I was unable to upload a user image.
However, upon checking my custom API, I realized that after adding an SSL certificate to my website that I had not updated the api.swift URLs, the data was unable to post:
let HOME_URL = "http://sitename.io"
let BASE_URL = "http://sitename.io/api"
let UPLOAD_URL = "http://sitename.io/api/user/upload"
I changed the URL's to https://. Problem solved.
In my case I have to add this Key: "Accept":"application/json" to my header request.
Something like this:
let Auth_header: [String:String] = ["Accept":"application/json", "Content-Type" : "application/json", "Authorization":"Bearer MyToken"]
I hope that this can help someone.
I face same issue and problem is in params.
let params = [kService: service,
kUserPath: companyModal.directory_path,
kCompanyDomain: UserDefaults.companyDomain,
kImageObject: imageString,
kEntryArray: jsonString,
kUserToken: UserDefaults.authToken] as [String : Any]
companyModal.directory_path is url. it coerced from string to any which create issues at server side. To resolve this issue I have to give default value which make it string value.
let params = [kService: kGetSingleEntry,
kUserPath: companyModal.directory_path ?? "",
kCompanyDomain: UserDefaults.companyDomain,
kUserToken: UserDefaults.authToken,
kEntryId: id,
] as [String: Any]
Probably you have "/" at the end of your path. If it is not GET request, you shouldn't put "/" at the end, otherwise you'll get the error
I Changed mimeType from "mov" to "multipart/form-data".
Alamofire.upload(multipartFormData: { (multipartFormData) in
do {
let data = try Data(contentsOf: videoUrl, options: .mappedIfSafe)
let fileName = String(format: "ios-video_%#.mov ", profileID)
multipartFormData.append(data, withName: "video", fileName: fileName, mimeType: "multipart/form-data")
} catch {
completion("Error")
}
}, usingThreshold: .init(), to: url,
method: .put,
headers: header)
Worked for me.. :)
For my case:
let header = ["Authorization": "Bearer \(Authserices.instance.tokenid)"]
I forgot the space before \ (after Bearer)
In my case error was due to duplicate email. You can recheck your API on postman to see if response there is OK or not.
In my case, I tried using Postman to get API and this error come from backend.

Resources