Issue with parsing json using Alamofire - ios

My JSON response in postman looks like this...
{
"success": 1,
"Details": {
"seller_id": "165",
"mobile_no": "9653265987",
"seller_name": "User A",
"seller_email_id": "user#gmail.com",
"company_name": "myCompany",
"category": "Cosmetics",
"otp": "1111"
},
"message": "Seller Already Registered!!!"
}
Now I wanted to give a condition based on whether success is 0 or 1 and so for that I wanted to extract success. Also I want to extract mobile number. But I am not able figure out how to do that.
This is how I am making my Alamofire post request...
Alamofire.request(url, method: .post, parameters: Parameters, encoding: URLEncoding.httpBody, headers: headers)
.responseString { (response) in
if let httpResponse = response.response {
print("error \(httpResponse.statusCode)")
if httpResponse.statusCode == 200 {
//Do something
}
}
}
I did go through similar issues raised by other users...but couldn't find from them an exact solution for my issue...

Try this
Alamofire.request(url, method: .post, parameters: Parameters, encoding: URLEncoding.httpBody, headers: headers)
.responseJSON { (response) in
switch response.result{
case .success(_):
print("Success: \(response)")
let JsonResponse = response.result.value as? [String: Any]
if JsonResponse?["success"] as! Int == 1{
let dict = JsonResponse?["Details"] as! [String : Any]
let mobileNo = dict["mobile_no"] as! String
}
else{
print("Failed")
}
case .failure(let error):
print("Failed: \(error)")
}
}

There are a couple of issues:
Your parameters to request don't look quite right.
the parameters parameter doesn't look right: at best, it's very strange to have a Parameters variable (you should use lower case for variables; and this conflicts with an Alamofire type);
the encoding should be URLEncoding.default. Or, because URLEncoding.default is the default value, you can omit this altogether.
If you want to check for status code, let validate do that for you.
If you're expecting JSON in response, use reponseJSON instead of responseString.
Use if let or guard let with as? to safely unwrap optionals. Do not use as! (unless you are 100% sure that it never could fail ... and when dealing with responses from a remote server, you can never be 100% confident).
Thus:
func performRequest(url: String, parameters: [String: String]?, headers: [String: String]?) {
Alamofire.request(url, method: .post, parameters: parameters, headers: headers)
.validate(statusCode: 200 ..< 300)
.responseJSON { response in
switch response.result {
case .success(let value):
guard let dictionary = value as? [String: Any],
let success = dictionary["success"] as? Int else {
print("success not found")
return
}
guard success == 1 else {
print("web service reported failure")
return
}
guard let details = dictionary["Details"] as? [String: Any] else {
print("Did not find details")
return
}
guard let mobile = details["mobile_no"] as? String else {
print("mobile not found")
return
}
print(mobile)
case .failure(let error):
print("Failed: \(error)")
}
}
}
Or, in your comment below, if you want to goToSignUpScreen() if success was 0, then:
Alamofire.request(url, method: .post, parameters: parameters, headers: headers)
.validate(statusCode: 200 ..< 300)
.responseJSON { response in
switch response.result {
case .success(let value):
guard let dictionary = value as? [String: Any],
let success = dictionary["success"] as? Int else {
print("success not found")
return
}
if success == 0 {
self.goToSignUpScreen()
}
case .failure(let error):
print("Failed: \(error)")
}
}

Related

Alamofire Value of type 'Result<Any, AFError>' has no member 'isSuccess' (Swift 5)

I have a simple procedure, which I used in my earlier version (Swift 4). I have now updated to the new version (Swift 5, Alamofire 5.0.0-rc.2), as I am still beginner I got problems with this. Some code parts I could already rewrite.
let headers: HTTPHeaders = [
"SubscriptionKey": SubscriptionKey,
"Host": HostName
]
AF.request(URL(string: userInfoUrl)!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers)
.validate()
.responseJSON { response in
guard response.result.isSuccess else {
log.error("Error requesting user ID: \(String(describing: response.result.error))")
completion(false, nil)
return
}
guard let json = response.result.value as? [String: Any], let userId = json["userId"] as? String else {
log.error("Malformed result from API call.")
completion(false, nil)
return
}
response.result.isSuccess is not possible. How can I reuse this part?
Error: Value of type 'Result' has no member 'isSuccess'
As a possible solution, I will test the above solution.
AF.request(URL(string: userInfoUrl)!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers)
.validate()
.responseJSON { response in
switch response.result{
case .success(let value):
//succcess, do anything
case .failure(let error):
log.error("Error requesting user ID: \(String(describing: response.error))")
completion(false, nil)
return
}
Result is containing .success or .failure case.
So you should treat isSuccess like this
switch response.result {
case .success(let value):
//success, do anything
case .failure(let error):
//failure
}

How to get key Value from post webservice API and fetch that to tableview

I got data from API in this format but the problem is that I want to get all questions and answers from the API but whenever I try to get the value by using the key value it returns nil value and application crashes
this is my api data looks like after getting into a dictionary
here's my code for getting data from API
Alamofire.request(url, method: .post, parameters: parameters,encoding: JSONEncoding.default, headers: header ).responseJSON {
response in
switch response.result {
case .success:
print(response)
if let result = response.result.value {
print(result)
let responseDict = result as! [String : Any]
print(responseDict)
let data = responseDict["Result"] as! [Any]
print(data)
}
break
case .failure(let error):
print(error)
}
}
You can try
if let res = responseDict["Result"] as? [[String:Any]] {
for item in res {
if let ques = item["Question"] as? String {
print(ques)
}
if let op = item["Options"] as? [[String:Any]] {
print(op)
}
}
}

How to send request in Alamofire 4.0 only with parameters and Body using POST method in swift?

I am using like this, but in this case, I need to call API with parameters and Body. Please help me. Thanks in advance.
Alamofire.request(postUrl, method: .post, parameters: params, encoding: CustomPostEncoding(), headers: nil).validate().responseJSON{ response in
switch response.result
{
case .success:
MBProgressHUD.hide(for: self.view, animated: true)
if let val = response.result.value
{
let json = JSON(val)
print(json)
}
case .failure(let error):
print(error)
}
}
var url = "http://..."
let _headers : HTTPHeaders = ["Content-Type":"application/x-www-form-urlencoded"]
let params : Parameters = ["grant_type":"password","username":"mail","password":"pass"]
let url = NSURL(string:"url" as String)
request(url, method: .post, parameters: params, encoding: URLEncoding.httpBody , headers: _headers).responseJSON(completionHandler: {
response in response
let jsonResponse = response.result.value as! NSDictionary
if jsonResponse["access_token"] != nil
{
access_token = String(describing: jsonResponse["accesstoken"]!)
}
})
Refrence :- POST request with a simple string in body with Alamofire
use your parameters instead of class_id ,and time.
func listOfClassesData(url: String,class_id: String,time: String,redClassesData : [String: Any] ,completionHandler:#escaping (Bool) -> ()){
let Auth_header = ["Authorization" : "Bearer "+getBearerToken()]
let paameters:Parameters = [
"class_id" : class_id,
"time" :time,
]
print(url,Auth_header)
Alamofire.request(url, method: .post, parameters: paameters, encoding: JSONEncoding.default, headers: Auth_header)
.responseJSON { response in
print(response)
switch response.result{
case .success:
let statusCode: Int = (response.response?.statusCode)!
switch statusCode{
case 200:
if let json = response.result.value{
completionHandler(true)
}
break
default:
completionHandler(false)
break
}
break
case .failure:
completionHandler(false)
break
}
}
}
let url = "your api url"
let param = ["user":"user#test.com","pass":"12345"]
Alamofire.request(url, method: .post , parameters: param)
.validate()
.responseJSON {
response in
switch response.result{
case .success:
var jsonResult = [String:AnyObject]()
do
{
//Get response successfully of api
jsonResult = try JSONSerialization.jsonObject(with: response.data!, options: []) as! [String:AnyObject]
print(jsonResult)
}
catch let error as NSError {
//get error if there is any problem in response of api.
print("--->",error)
}
case .failure(let error):
//get error if there is any problem while calling api.
print("---->",error)
}
}

Alamofire Parameter missing in response

I install pod file of Alamofire for calling web service and successfully retrieve data when there is no parameter pass to web service but when I try to pass parameter It shows this parameter missing.
Here is my code:
let parameters: Parameters = ["client_id": "1","user_token":"A4YkkH5FdTbRCI8Mk98s"]
let url = "http://***********/index.php/Web_api/get_client_profile"
Alamofire.request(url , method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if response.result.value != nil{
print(response.result.value)
}
break
case .failure(_):
print(response.result.error)
break
}
}
RESPONSE:
{
"message : client_id parameter missing",
"Code : 500"
}
What I am doing wrong ? Please help me with it.
Thank you
After banging my head for like 6 Hours I figured a different approach, here is a way of calling it, which works:
var request: Alamofire.Request? {
didSet {
oldValue?.cancel()
}
}
func loadDataFromServer(message:String?) {
// Prerequisites for Connection to Server
let timeParameter = self.getLastTimeStamp()
let url = "http://your.amazing.url/path/component/classs"
let parameter = ["timestamp":timeParameter]
//sho hud only of there is no data listed
if message != nil {
HUD.show(HUDContentType.label("Loading.."))
}
self.request = Alamofire.request(url, method: .post, parameters:parameter)
if let request = request as? DataRequest {
request.responseString { response in
PKHUD.sharedHUD.hide()
do{
let dictionary = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
//Save and Fetch
self.saveTimestamp(dictionary: dictionary, wsEntity: "Section")
self.saveDataInPersisanceStorage(articalDictionary: dictionary)
self.fetchDatafromCore()
//HUD.flash(.success, delay:1.0)
}catch{
//HUD.flash(.error, delay:1.0)
}
}
}
}

Alamofire completion handler not being called

I'm currently trying to call a prepareForSegue method in an AlamoFire completion handler but it's not being called. Here is my code:
func loginMember (username: String, password: String, completionHandler: (String?, ErrorType?) -> ()) {
let headers = [
"Cache-Control": "no-cache",
"Content-Type": "application/json"
]
let parameters: [String: AnyObject] = [
"grant_type" : "password",
"username" : username,
"password" : password,
]
Alamofire.request(.POST, "\(baseURL)/oauth2/token", parameters: parameters, encoding: .JSON, headers: headers)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
guard let value = response.result.value else {
completionHandler(nil, response.result.error)
return
}
let swiftyJsonVar = JSON(value)
accessToken = swiftyJsonVar["access_token"].stringValue
print("This is the login response:\(swiftyJsonVar)")
case .Failure(let error):
print("Sorry there was an error: \(error)")
return
}
}
}
This is what it looks like when called:
loginMember(username, password: password, completionHandler: { error in
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("loginToHomeSegue", sender: self)
}
}
)
Any ideas as to why the performSegueWithIdentifier isn't being called?
You're only calling your completion handler in the case where you enter your guard statement. You need to add calls for the case where you get your access token and your error case.
Alamofire.request(.POST, "\(baseURL)/oauth2/token", parameters: parameters, encoding: .JSON, headers: headers)
.validate()
.responseJSON { response in
switch response.result {
case .Success:
guard let value = response.result.value else {
completionHandler(nil, response.result.error)
return
}
let swiftyJsonVar = JSON(value)
accessToken = swiftyJsonVar["access_token"].stringValue
print("This is the login response:\(swiftyJsonVar)")
// Got the token, call handler
completonHandler(accessToken, nil)
case .Failure(let error):
print("Sorry there was an error: \(error)")
// Got an error, call handler
completionHandler(nil, error)
return
}
}

Resources