convert alamofire json response to variable - ios

I have a question that I already asked several times on stackoverflow and I have tried all of them, there is none of them worked. So I would love to summarize the question for another time, and try to describe it more precise.
I am building an app sending a picture to a python back end for the result of image recognition in xcode swift.
And I am using Alamofire to upload,
here is the uploading part:
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData!, withName: "pic", fileName: "filename.png", mimeType: "image/png")
}, to: "http:123456.com/image",
method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseString { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
And here is the json response I got from the server end:
[Response]: <NSHTTPURLResponse: 0x600000237de0> { URL: 1234/image } { Status Code: 200, Headers {
"Content-Length" = (
348
);
"Content-Type" = (
"text/html; charset=utf-8"
);
Date = (
"Mon, 09 Apr 2018 20:59:30 GMT"
);
Server = (
"Werkzeug/0.12.2 Python/2.7.12"
);
} }
[Data]: 348 bytes
[Result]: SUCCESS: {
"prediction": [
{
"name": "marshmallow",
"value": 0.2800232470035553
},
{
"name": "caesar salad",
"value": 0.090629942715168
},
{
"name": "egg",
"value": 0.07480788230895996
},
{
"name": "apple",
"value": 0.049235329031944275
},
{
"name": "chickpea",
"value": 0.04692944884300232
}
]
}
[Timeline]: Timeline: { "Request Start Time": 545000363.584, "Initial Response Time": 545000363.642, "Request Completed Time": 545000370.462, "Serialization Completed Time": 545000370.487, "Latency": 0.058 secs, "Request Duration": 6.879 secs, "Serialization Duration": 0.025 secs, "Total Duration": 6.903 secs }
So, the purpose I want to have, is just print the name of the first prediction's name.
like the output is
outcome is marshmallow with a value of 0.28
I have tried several ways:
First, I want to have a struct to store the name as string, value as double, and use a loop to parse it. But whatever I tried, I always get a "null" as output, or nothing.
Any suggestions on this? Thanks in advance.

try this:
upload.responseJSON { response in
if let result = response.result.value {
let json = result as! [String: Any]
if let predictionArray = json["prediction"] as? [[String: Any]],
let firstPrediction = predictionArray.first {
print(firstPrediction)
}
print(json)
}
}

Related

Post multiple object data in alamofire

The number of posts is available in StackOverflow but i can't get the solution, I am using Alamofire Library and post my result to hit API but I'm not able to get the result please help me to fix it.
{
"People":{ "Prefix": "Mr.",
"FirstName": "Eric",
"MiddleName": null,
"LastName": "John",
"FullName": "Smith GOldi6",
"Email1": "abc123#example.com",
"Email2": null,
"PhoneNumber1": "0000",
"PhoneNumber2": null,
"DateOfBirth": "1975-01-01T00:00:00",
"Status": 3,
"DeleteFlag": true,
"Comments": null,
"Description": null,
"UserName": "abc123"
},
"Password": "password1"
}
this is the result which I create in parameters to post.
Alamofire.request(signup_api, method: .post, parameters: parameters, encoding: URLEncoding.httpBody).responseJSON { (response) in
switch response.result {
case .success(let data) :
let json = JSON(data)
print("response.result = \(response.result)")
print("response = \(response)")
let resJson = JSON(response.result.value!)
print("success = \(resJson)")
if (resJson.count == 0) {
if (resJson.null == nil) {
// self.DimBackground.isHidden = true
// self.activator.stopAnimating()
}
return
}
if let err = response.error{
print("err === \(err)")
return
}
return
case .failure(let _error):
print("_error = \(_error)")
print("false")
print("response.result = \(response.result)")
print("response = \(response)")
print("Network Problem: There might be an issue with your internet connection, or server not responding. Please try again.")
return
}
}
This shows this error:
_error = responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error:
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around
character 0." UserInfo={NSDebugDescription=Invalid value around
character 0.})) false response.result = FAILURE response = FAILURE:
responseSerializationFailed(reason:
Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error:
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around
character 0." UserInfo={NSDebugDescription=Invalid value around
character 0.}))
if you are getting proper JSON response than there should be issue in your condition
if (resJson.count == 0)
Actually there should be status (true/false) in your response so you get idea which action you need to take if status is true than you have to get proper data from response and processed for further. else you have to show error message and stop for processed further.

Uploading text file using Alamofire

I have a text file saved in a directory inside the document directory
I want to upload this file to stream (upload) to the server using Alamofire but I'm getting an error and I don't follow what is the error mean
the response should be a string, the problem isn't in the format of the response data even if I used responseString I'm getting an error.
This my code:
let folder = getFolder()
let textFile = fileUrl?.appendingPathComponent(fileTemp)
let headers: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
let finalUrl = url + "/myMethod"
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(textFile!, withName: "file")
},
to: finalUrl,headers:headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}})
And this is the response value I am getting:
Status Code: 400, Headers {
"Cache-Control" = (
private
);
"Content-Length" = (
1647
);
"Content-Type" = (
"text/html"
);
Date = (
"Thu, 06 Sep 2018 09:32:47 GMT"
);
Server = (
"Microsoft-IIS/8.5"
);
"X-AspNet-Version" = (
"4.0.30319"
);
"X-Powered-By" = (
"ASP.NET"
); } } [Data]: 1647 bytes [Result]: FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
3." UserInfo={NSDebugDescription=Invalid value around character 3.}))
Does anyone have any idea about what I'm doing wrong?
Thanks in advance!
you need to specify the upload format is text
Change this:
multipartFormData.append(textFile!, withName: "file")
To this:
multipartFormData.append(textFile!, withName: "file", fileName: filename, mimeType: "text/plain")

ObjectMapper failed to serialize response error Code=2

Im getting an error while hitting Alamofire get request using Alamofire Object mapper
this is how i'm hitting the API-
APIService.shared.getSlots{ (success,weekSlots, error) in
if success {
self.weekSlots = weekSlots!
print("success!!")
} else {
print(error?.errorMessage ?? "NOPE")
}
}
while getSlot function inside APIService class is-
open func getSlots(completion: #escaping (Bool, [WeekSlot]?, APIError?) -> ()) {
sessionManager.request(APIRouter.getSlots())
.validate(statusCode: 200..<300)
.responseArray(queue: nil,
keyPath: "week_slots",
context: nil) { (response: DataResponse<[WeekSlot]>) in
switch response.result {
case .success(let value):
self.saveArraysToRealm(value: value)
completion(true,value, nil)
case .failure:
let error = self.processFailure(json: JSON(response.data as Any))
completion(false, nil, error)
print(error)
}
}
}
this is my Data model :
import Foundation
import ObjectMapper
import RealmSwift
class WeekSlot: Object, Mappable {
dynamic var date : String? = ""
var slot = List<Slots>()
//Impl. of Mappable protocol
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
date <- map["date"]
slot <- (map["slots"], ArrayTransform<Slots>())
}
}
Ive declared the request to perform get request and the url is also correct. The API does not accept any parameters except auth token which is handled by sessionManager. However, im getting the following error in response while debugging-
[Request]: GET http://beta.xamidea.in/api/v1/teachers/get_slots/
[Response]: <NSHTTPURLResponse: 0x600000434c80> { URL: http://beta.xamidea.in/api/v1/teachers/get_slots/ } { status code: 200, headers {
Allow = "GET, POST, HEAD, OPTIONS";
Connection = "keep-alive";
"Content-Length" = 477;
"Content-Type" = "application/json";
Date = "Tue, 10 Oct 2017 11:01:53 GMT";
Server = "nginx/1.10.3 (Ubuntu)";
Vary = Accept;
"X-Frame-Options" = SAMEORIGIN;
} }
[Data]: 477 bytes
[Result]: FAILURE: Error Domain=com.alamofireobjectmapper.error Code=2 "ObjectMapper failed to serialize response." UserInfo=. {NSLocalizedFailureReason=ObjectMapper failed to serialize response.}
[Timeline]: Timeline: { "Request Start Time": 529326113.851, "Initial Response Time": 529326113.985, "Request Completed Time": 529326113.986, "Serialization Completed Time": 529326113.987, "Latency": 0.134 secs, "Request Duration": 0.135 secs, "Serialization Duration": 0.001 secs, "Total Duration": 0.136 secs }
▿ request : Optional<URLRequest>
▿ some : http://beta.xamidea.in/api/v1/teachers/get_slots/
▿ url : Optional<URL>
▿ some : http://beta.xamidea.in/api/v1/teachers/get_slots/
- cachePolicy : 0
- timeoutInterval : 60.0
- mainDocumentURL : nil
- networkServiceType : __ObjC.NSURLRequest.NetworkServiceType
- allowsCellularAccess : true
▿ httpMethod : Optional<String>
- some : "GET"
▿ allHTTPHeaderFields : Optional<Dictionary<String, String>>
▿ some : 1 element
▿ 0 : 2 elements
- key : "Authorization"
- value : "Token 4d7ebe501bcd7c910cf1950ab53bc8aa2a4a569d"
- httpBody : nil
- httpBodyStream : nil
- httpShouldHandleCookies : true
- httpShouldUsePipelining : false
▿ response : Optional<NSHTTPURLResponse>
▿ data : Optional<Data>
▿ some : 477 bytes
- count : 477
▿ pointer : 0x00007f896a48aa80
- pointerValue : 140228170394240
▿ result : FAILURE: Error Domain=com.alamofireobjectmapper.error Code=2 "ObjectMapper failed to serialize response." UserInfo= {NSLocalizedFailureReason=ObjectMapper failed to serialize response.}
▿ timeline : Timeline: { "Request Start Time": 529326113.851, "Initial Response Time": 529326113.985, "Request Completed Time": 529326113.986, "Serialization Completed Time": 529326113.987, "Latency": 0.134 secs, "Request Duration": 0.135 secs, "Serialization Duration": 0.001 secs, "Total Duration": 0.136 secs }
- requestStartTime : 529326113.85062999
- initialResponseTime : 529326113.98505801
- requestCompletedTime : 529326113.98612601
- serializationCompletedTime : 529326113.986781
- latency : 0.13442802429199219
- requestDuration : 0.13549602031707764
- serializationDuration : 0.00065499544143676758
- totalDuration : 0.1361510157585144
▿ _metrics : Optional<AnyObject>
What does this error means??
the response from API on success is this-
{
"result": {
"week_slots": [
{
"date": "2017-10-10",
"slots": []
},
{
"date": "2017-10-11",
"slots": [
{
"start": "2017-10-11T20:00:00Z",
"end": "2017-10-11T21:00:00Z",
"availability": true,
"booked": false
},
{
"start": "2017-10-11T10:00:00Z",
"end": "2017-10-11T12:00:00Z",
"availability": true,
"booked": false
}
]
},
{
"date": "2017-10-12",
"slots": []
},
{
"date": "2017-10-13",
"slots": []
},
{
"date": "2017-10-14",
"slots": []
},
{
"date": "2017-10-15",
"slots": []
},
{
"date": "2017-10-16",
"slots": []
}
]
},
"success": true,
"error": {}
}
I found the solution after 1 day, the problem was in keyPath to access "week_slots" , since I was using swiftyjson the correct way to accesss was:
keyPath: "result.week_slots"
So basically whenever you get this error even when the responce from is is success, its because you are unable to map the response in your model correctly
try changing the model class as:
class WeekSlot: Object, Mappable {
dynamic var date : String? = ""
var slot: [Slots] = []
//Impl. of Mappable protocol
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
date <- map["date"]
slot <- map["slots"]
}
}
also check your slot model

Problems with JSON and Alamofire request

I am trying to send a request with the next code:
func getLogin(user: String, password: String) {
let url = URL(string: "https://www.url.es/api/login")!
let parameters: Parameters = [
"usuario" : "\(user)",
"clave" : "\(password)"]
let headers: HTTPHeaders = [
"Authorization": "Basic TOKEN"
]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).validate()
.responseJSON { response in
print("repuesta")
print(response.request as Any) // original URL request
print(response.response as Any) // URL response
print(response.result.value as Any) // result of response serialization
debugPrint(response)
}
}
But I am getting this response:
[Request]: https://www.url.es/api/login
[Response]: <NSHTTPURLResponse: 0x608000220b40> { URL: https://www.url.es/api/login } { status code: 401, headers {
"Cache-Control" = "no-cache";
"Content-Length" = 28;
"Content-Type" = "text/plain; charset=utf-8";
Date = "Mon, 16 Jan 2017 20:44:14 GMT";
Expires = "-1";
Pragma = "no-cache";
Server = "Microsoft-IIS/8.5";
"Www-Authenticate" = Bearer;
"X-AspNet-Version" = "4.0.30319";
"X-Powered-By" = "ASP.NET";
} }
[Data]: 28 bytes
[Result]: FAILURE: responseValidationFailed(Alamofire.AFError.ResponseValidationFailureReason.unacceptableStatusCode(401))
[Timeline]: Timeline: { "Request Start Time": 506292395.911, "Initial Response Time": 506292396.351, "Request Completed Time": 506292396.352, "Serialization Completed Time": 506292396.353, "Latency": 0.440 secs, "Request Duration": 0.441 secs, "Serialization Duration": 0.000 secs, "Total Duration": 0.441 secs }
I am sending the request with paw http client and the response is ok.
I am working with swift3, alamofire 4 and iOS10
According to the response you have there it looks like your username and password is incorrect. Try printing the parameters dictionary to make sure it is correct. Something that can happen sometimes is if you forget to unwrap an optional value it will still get sent. For example
let optionalString:String? = "blablabla"
print(optionalString) //prints: Optional(blablabla)
Edit:
Another thing I noticed is you set the encoding to JSON but the header Content Type is PlainText. Try setting the encoding to URLEncoding.default and make sure the headers are set appropriately for what the server is expecting.

Alamofire HTTP requests fails

I made some HTTP requests using Alamofire. Some request has been succeeded and some are failed.
error is Invalid value around character 0.
Failed request gave me above error.
bellow i have mentioned a sample code which failed.
let parameters = ["amount": ["10"], "payment_method": ["paypal"], "date": ["2015-11-25"], "details": ["Payment description"]]
let headers = [
"Accept": "*/*",
"Content-Type": "application/json"
]
let url = "https://livetest.somedomain.com/api/invs/LAT1j5da99PdPg/payments?auth_token=pbtTEPNki3hUhGBuPX3d"
Alamofire.request(.POST, url, parameters: parameters, encoding: .JSON, headers: headers)
.responseJSON { response in
let results = response.result
print(results)
print(response.debugDescription)
}
Please help me to find the issue
This issue was happened because of wrong format of JSON passing. Then i changed the parameter as follows
let parameters = ["payment":["amount": "100" , "payment_method": "check", "date": "2015-11-25", "details": "Payment description dimuth Lasantha"]]
Now it passes the correct format which is
{
payment: {
"amount" : "100",
"payment_method" : "check",
.....
}
}

Resources