Alamofire: NSLocalizedFailure error (status code 403) - ios

I am trying to retrieve the various user ids from task api, perform a loop on them and POST the array of values to submitScore api.
Desired workflow:
User taps on table cell -> app gets the cell id and display items related to that cell -> user presses a button -> app gets stores data in the form of an array and POSTS to an submitScore api
I can retrieve the various user data with a GET request from task api but I don't know how to:
associate my retrieved ids with the cell id
store the retrieved data (user ids and score) in an array and POST it to my submitScore api in the form below
Array form for POST body:
{ "ratings": [{
"safety_rating_id": 105,
"schedule_job_id": 18,
"score": 9,
"submission_id": 27
},
{
"safety_rating_id": 105,
"schedule_job_id": 18,
"score": 9,
"submission_id": 27
}]
}
Which is why I get thrown this error:
Request failed with error: Error Domain=com.alamofire.error Code=-6003 "Response status code was unacceptable: 403" UserInfo={NSLocalizedFailureReason=Response status code was unacceptable: 403}
Code for POST:
func getTaskDetails(onCompletion: () -> (), onError: ((NSError) -> ())? = nil) {
guard let endPoint = Data.sharedInstance.submitScoreEndpoint
else { print("Empty endpoint"); return }
let user = Users()
let Auth_header = [
"Authorization" : user.token,
]
let parameters = [
"ratings" : [
[
"safety_rating_id" : 106,
"schedule_job_id" : 18,
"score" : 10,
"submission_id" : 27
],
[
"safety_rating_id" : 105,
"schedule_job_id" : 18,
"score" : 9,
"submission_id" : 27
]
]
]
Alamofire.request(.POST, endPoint, headers: Auth_header, parameters: parameters)
.validate()
.responseData {
response in
switch response.result {
case .Success(let data):
let json = JSON(data)
print(json)
onCompletion()
case .Failure(let error):
print("Request failed with error: \(error)")
onError?(error)
}
}
}

Related

Failed response from **Alamofire** in swift 5

I'm using Alamofire class for api calling. Api is working properly in Postman
please check below two screenshots for reference,
in first image data is passing inside raw body
in second image data is passing inside Headers field
now i'm using this code to call API
//for params i'm sending below parameters
//["phoneNumber":"911234567890", "countryCode" : "91"]
let headers: HTTPHeaders = [
"deviceId" : deviceId,
"osVersion": osVersion,
"deviceType": deviceType,
"resolution":resolution,
"buildNumber":buildNumber]
AF.request(strURL, method: .post, parameters: params, encoding: JSONEncoding.default, headers:headers).responseData { (response) in
switch response.result {
case .success(let data):
do {
//let asJSON = try JSONSerialization.jsonObject(with: data)
let asJSON = try JSONSerialization.jsonObject(with: data, options: [.fragmentsAllowed])
// success
print(asJSON)
let res : NSDictionary = (asJSON as AnyObject) as! NSDictionary
successBlock(res)
} catch { // error
print("decoding error:\n\(error)")
}
case .failure(let error):
print(error)
failure(error)
}
}
in all other project above code is working fine for api calling, but here i'm getting below error
{ code = 500; data = ""; message = "Failed to convert value of type 'java.lang.String' to required type 'java.util.Locale'; nested exception is java.lang.IllegalArgumentException: Locale part "en;q=1.0" contains invalid characters"; …………………… NamedValueMethodArgumentResolver.java:125)\n\t... 97 more\n"; status = "INTERNAL_SERVER_ERROR"; timestamp = "01-03-2022 07:55:20"; }
i've try several methods like URLEncoding.default, passing custom header, create custom raw request & passed header inside but nothing works,
AnyOne have solution for this issue?
Thanks in Advance.
As it is throwing error related to Local, I think some language is defined and it doesn't accept * for Accept-Language header, try sending "en" in the header Accept-Language.
Check subtags for language:
http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry :
Test Code:
func callAPI() {
let params: Parameters = ["phoneNumber":"911234567890", "countryCode" : "91"]
let headers = [
"deviceId" : "jdhcbkerfjkr",
"osVersion": "3.2.3",
"deviceType": "ANDROID",
"resolution": "122x122",
"buildNumber": "3.2.1",
"Accept-Language": "en"]
AF.request("[Test-URL]",
method: .post,
parameters: params,
encoding: JSONEncoding.default,
headers: HTTPHeaders.init(headers)).response { response in
print(String(data: response.data!, encoding: .utf8)!)
}
}

How to make network calls from Siri Intent Extension?

I am trying to integrate Siri from my app. Actually my requirement is do some UDP call with my server but as it was not happening I tried with simple network call with URLSession and URLRequest. For testing I am trying to visit google.com and print the response, but the retured data from the completion handler is not convertible to String and is returning nil. Is the anything I need to add extra either in the Info.plist file or in other places to make the network calls succeed in Intent Extension ?
In the official documentation also there is no mention of this. The code I am using is simple actually but still I am pasting that below:
let session = URLSession.shared
let task = session.dataTask(with: URLRequest(url: URL(string: "https://www.google.com/")!), completionHandler: { (tcpData, response, error) in
if error != nil {
print("tcp error \(error!.localizedDescription)")
}
if let res = response as? HTTPURLResponse {
print(res.statusCode)
}
if tcpData != nil {
print(String(data: tcpData!, encoding: String.Encoding.utf8) ?? "N/A")
}
})
task.resume()
completion(TurnOnNodeAppIntentResponse.init(code: TurnOnNodeAppIntentResponseCode.success, userActivity: nil))
here is the response is always nil though statusCode is 200.
There is nothing wrong with your code. Not all data can be converted to a String. You can read more about that in this answer. Just hitting https://www.google.com/ doesn't return a string. However, if you really want to print the a string of the data from https://www.google.com/ just use print(tcpData!.base64EncodedString()) and you'll get something like: PCFkb2N0eXBlIGh0bWw+PGh0bWwgaXRlbXNjb3BlPSIiIGl0ZW10eXBlPSJodHRwOi8vc....
Switch that URL to an open API like the SpaceX API and you'll get a valid string.
{
"flight_number": 83,
"mission_name": "Amos-17",
"mission_id": [
],
"launch_year": "2019",
"launch_date_unix": 1565131920,
"launch_date_utc": "2019-08-06T22:52:00.000Z",
"launch_date_local": "2019-08-06T18:52:00-04:00",
"is_tentative": false,
"tentative_max_precision": "hour",
"tbd": false,
"launch_window": 5280,
"rocket": {
"rocket_id": "falcon9",
"rocket_name": "Falcon 9",
"rocket_type": "FT",
"first_stage": {
"cores": [
{
"core_serial": "B1047",
"flight": 3,
"block": 5,
"gridfins": false,
"legs": false,
"reused": true,
"land_success": null,
"landing_intent": false,
"landing_type": null,
"landing_vehicle": null
}
]
},
"second_stage": {
"block": 5,
"payloads": [
{
"payload_id": "Amos-17",
"norad_id": [
],
"reused": false,
"customers": [
"Spacecom"
],
"nationality": "Israel",
"manufacturer": "Boeing Satellite Systems",
"payload_type": "Satellite",
"payload_mass_kg": 6500,
"payload_mass_lbs": 14330.05,
"orbit": "GTO",
"orbit_params": {
"reference_system": "geocentric",
"regime": "geostationary",
"longitude": 17,
"semi_major_axis_km": null,
"eccentricity": null,
"periapsis_km": null,
"apoapsis_km": null,
"inclination_deg": null,
"period_min": null,
"lifespan_years": 15,
"epoch": null,
"mean_motion": null,
"raan": null,
"arg_of_pericenter": null,
"mean_anomaly": null
},
"uid": "UerI6qmZTU2Fx2efDFm3QQ=="
}
]
},
"fairings": {
"reused": false,
"recovery_attempt": true,
"recovered": true,
"ship": "GOMSTREE"
}
},
"ships": [
"GOMSTREE",
"GONAVIGATOR"
],
"telemetry": {
"flight_club": null
},
"launch_site": {
"site_id": "ccafs_slc_40",
"site_name": "CCAFS SLC 40",
"site_name_long": "Cape Canaveral Air Force Station Space Launch Complex 40"
},
"launch_success": true,
"links": {
"mission_patch": "https://images2.imgbox.com/a0/ab/XUoByiuR_o.png",
"mission_patch_small": "https://images2.imgbox.com/f1/4a/WAkSmKfY_o.png",
"reddit_campaign": "https://www.reddit.com/r/spacex/comments/cjaawx/amos17_launch_campaign_thread",
"reddit_launch": "https://www.reddit.com/r/spacex/comments/cmedgn/rspacex_amos17_official_launch_discussion_updates",
"reddit_recovery": null,
"reddit_media": "https://www.reddit.com/r/spacex/comments/cmppne/rspacex_amos17_media_thread_videos_images_gifs",
"presskit": "https://www.spacex.com/sites/spacex/files/amos-17_mission_press_kit_8_6_2019.pdf",
"article_link": "https://spaceflightnow.com/2019/08/07/spacex-launches-israeli-owned-telecom-satellite/",
"wikipedia": "https://en.wikipedia.org/wiki/Spacecom",
"video_link": "https://youtu.be/fZh82-WcCuo",
"youtube_id": "fZh82-WcCuo",
"flickr_images": [
"https://live.staticflickr.com/65535/48478269312_58dd3dc446_o.jpg",
"https://live.staticflickr.com/65535/48478269747_353dcb2e62_o.jpg",
"https://live.staticflickr.com/65535/48478119901_2de0441026_o.jpg",
"https://live.staticflickr.com/65535/48478120646_ab72c2c6c3_o.jpg",
"https://live.staticflickr.com/65535/48478120031_5aae1f6131_o.jpg",
"https://live.staticflickr.com/65535/48478269442_08479bed36_o.jpg"
]
},
"details": "SpaceX will launch Boeing built Amos-17, a geostationary communications satellite for Israeli company Spacecom. The satellite will be delivered to GTO from KSC LC-39A or possibly CCAFS SLC-40, and will replace the defunct Amos-5 at 17° E. Amos-17 carries multi-band high throughput and regional beams servicing Africa, Europe and the Middle East. The cost of this launch is covered for Spacecom by SpaceX credit following the Amos-6 incident. A recovery of the booster for this mission is not expected.",
"upcoming": false,
"static_fire_date_utc": "2019-08-01T00:00:00.000Z",
"static_fire_date_unix": 1564617600,
"timeline": null,
"crew": null
}
Also you might want to stop force unwrapping and instead use if let or guard
let session = URLSession.shared
let task = session.dataTask(with: URLRequest(url: URL(string: "https://api.spacexdata.com/v3/launches/latest")!), completionHandler: { (tcpData, response, error) in
if let err = error {
print("tcp error \(err.localizedDescription)")
}
if let res = response as? HTTPURLResponse {
print(res.statusCode)
}
if let data = tcpData {
print(String(data: data, encoding: String.Encoding.utf8) ?? "N/A")
}
})
task.resume()
completion(TurnOnNodeAppIntentResponse.init(code: TurnOnNodeAppIntentResponseCode.success, userActivity: nil))

convert alamofire json response to variable

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)
}
}

REST API: Cannot populate Tableview

I am trying to pull data from an api to populate my table but nothing is being shown. How can I fix it?
UPDATED
When I place the GET request in either viewDidLoad() or viewDidAppear() I would receive an empty array
result of GET is []
I have tried adding self.tableView.reload() to the viewDidLoad() but would be thrown this error
Ambiguous reference to member 'tableView(_:numberOfRowsInSection:)'
This is my JSON response
[
{
"schedule_job_id": 23,
"start_date": "2016-05-01",
"end_date": "2016-05-08",
"building_id": 2,
"building_name": "Republic Plaza",
"building_block_no": "69A",
"building_street_name": "9 Raffles Place Downtown Core",
"building_postal_code": "233645",
"checklist_id": "1",
"checklist_name": "Lightning protection",
"checklist_due_date": "2016-04-12 17:00:00",
"tasks": [
{
"submission_id": 105,
"task_id": "1",
"task_name": "Inspect Carpark",
"task_checked": true,
"task_submitted_date": "2016-05-04 04:39:01",
"task_comment": null,
"task_building_level": "1",
"task_description": "",
"task_status": "OK",
"total_rating": null,
"safety_ratings": [
{
"submission_id": 105,
"safety_rating_id": 79,
"task_id": "1",
"name": "Equipment",
"points": "10",
"score": "0"
}
],
"photos": []
}
]
This is my GET request
override func viewDidLoad() {
usernameLabel.text = Data.sharedInstance.userName
let url = "http://anyapi.com"
Alamofire.request(.GET, url).validate().responseJSON { response in
switch response.result {
case .Success(let data):
let json = JSON(data)
if let data = json["task_name"].arrayValue as [JSON]?{
self.datas = data
self.displayTask.reloadData()
print("result of GET is \(self.datas)")
}
case .Failure(let error):
print("Request failed with error: \(error)")
}
}
}
The entire tableview code can be seen here https://codeshare.io/aKknb
Seems like json["task_name"] is not an array and isn't at first level, instead is a property of the objects in the tasks array, thats why you are getting an empty array.
You should do something like this if you intent to show the taks in your tableview
if let data = json["tasks"].arrayValue as [JSON]?{
Because the code which makes your HTTP request is in the wrong method. You intended it to be in viewDidLoad(), but you actually put it in didReceiveMemoryWarning()
Instead of putting the population in viewDidLoad try it in viewDidAppear... that way the tableview is all setup and able to correctly populate.
you can start HTTP request in ViewWillAppear and reload the tableview.That way tableview gets properly loaded.

Sending JSON or SwiftyJSON through Alamofire POST

Similar questions to this have been posted before but with slight differences, namely:
Alamofire: Sending JSON as request parameter
POST multiple json objects in Alamofire POST method - Swift/IOS
Sending json array via Alamofire
being the last one, the closest to my current problem. However, this solution is not working for me.
The problem I am facing is that I'm trying to send through an Alamofire POST request, a JSON that I've built using SwiftyJSON. Like so:
let url = NSURL(string: orderProductsEndpoint)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue(requestToken, forHTTPHeaderField: "Authorization:")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let params = [ json.object ]
print(params)
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject( params, options: [])
Alamofire.request(request)
.responseString{ response in
switch response.result {
case .Success(let value):
print("gut")
print(value)
case .Failure(let error):
print("not gut")
print(error)
}
}
However, this is not working well because the API that I'm communicating with doesn't seem to recognize well the parameters that I'm sending.
But then I noticed that what I am sending is not a valid JSON. This is what I am sending:
[{
car = (
{
cant = 2;
id = 6;
name = "Saudi Plate";
},
{
cant = 1;
id = 5;
name = "Beef Wrap";
}
);
idUser = 58;
"total_loyalty_points" = 4200;
"total_price" = 42000;}]
But before converting my JSON to an object using
let params = [ json.object ]
It was a valid JSON validated through JSONLint and it looks like this
{
"total_price" : 42000,
"car" : [
{
"id" : "6",
"cant" : 2,
"name" : "Saudi Plate"
},
{
"id" : "5",
"cant" : 1,
"name" : "Beef Wrap"
}
],
"idUser" : 58,
"total_loyalty_points" : 4200
}
So the problem is that I was forced to change the structure of the JSON because it seems to be the only way to send it through Alamofire, by converting it into an object. Is there a way to actually send raw JSON through Alamofire?
Try setting the json encoding for your parameters in the Alamofire request.
Alamofire.request("http://...", method: HTTPMethod.post, parameters: parameters, encoding: JSONEncoding.default, headers: nil)
.responseJSON(completionHandler: {(response) in ... })
https://github.com/Alamofire/Alamofire#json-encoding
Try to get your params as Alamofire parameters i.e [String : Any].
Basically you want to send raw json with post method.
Below function will do a post request with raw json. Also this is with generics
func nwCallRawJSon<T: Decodable>(url : String, param : [String : Any],decodable: T.Type,onCompletion: #escaping (T?,Error?) -> Void){
AF.request(url, method: .post, parameters : param, encoding: JSONEncoding.default, headers: nil).validate(contentType: ["application/json"]).responseDecodable { (response: DataResponse<T,AFError>) in
switch response.result {
case .success(let data):
onCompletion(data,nil)
case .failure(let error):
onCompletion(nil,error)
}
}
}

Resources