Alamofire Get API Request Not Working as Expected

AlamoFire GET api request not working as expected

One way to handle this is to pass a closure (I usually call it a completionHandler) to your siteInfo function and call that inside Alamofire.request's closure:

func siteInfo(completionHandler: (String?, NSError?) -> ()) -> () {
Alamofire.request(.GET, MY_API_END_POINT).responseJSON {
(request, response, JSON, error) in

let info = JSON as? NSDictionary // info will be nil if it's not an NSDictionary
let str = info?["access_key"] as? String // str will be nil if info is nil or the value for "access_key" is not a String

completionHandler(str, error)
}
}

Then call it like this (don't forget error handling):

siteInfo { (str, error) in
if str != nil {
// Use str value
} else {
// Handle error / nil value
}
}

In the comments you asked:

So how would you save the info you collect from the get request if you
can only do stuff inside the closure and not effect objects outside of
the closure? Also, how to keep track to know when the request has
finished?

You can save the result of the get request to an instance variable in your class from inside the closure; there's nothing about the closure stopping you from doing that. What you do from there really depends on, well, what you want to do with that data.

How about an example?

Since it looks like you're getting an access key form that get request, maybe you need that for future requests made in other functions.

In that case, you can do something like this:

Note: Asynchronous programming is a huge topic; way too much to cover here. This is just one example of how you might handle the data you get back from your asynchronous request.

public class Site {
private var _accessKey: String?

private func getAccessKey(completionHandler: (String?, NSError?) -> ()) -> () {

// If we already have an access key, call the completion handler with it immediately
if let accessKey = self._accessKey {
completionHandler(accessKey, nil)
} else { // Otherwise request one
Alamofire.request(.GET, MY_API_END_POINT).responseJSON {
(request, response, JSON, error) in

let info = JSON as? NSDictionary // info will be nil if it's not an NSDictionary
let accessKey = info?["access_key"] as? String // accessKey will be nil if info is nil or the value for "access_key" is not a String

self._accessKey = accessKey
completionHandler(accessKey, error)
}
}
}

public func somethingNeedingAccessKey() {
getAccessKey { (accessKey, error) in
if accessKey != nil {
// Use accessKey however you'd like here
println(accessKey)
} else {
// Handle error / nil accessKey here
}
}
}
}

With that setup, calling somethingNeedingAccessKey() the first time will trigger a request to get the access key. Any calls to somethingNeedingAccessKey() after that will use the value already stored in self._accessKey. If you do the rest of somethingNeedingAccessKey's work inside the closure being passed to getAccessKey, you can be sure that your accessKey will always be valid. If you need another function that needs accessKey, just write it the same way somethingNeedingAccessKey is written.

public func somethingElse() {
getAccessKey { (accessKey, error) in
if accessKey != nil {
// Do something else with accessKey
} else {
// Handle nil accessKey / error here
}
}
}

Api call not working in alamofire but working in postman

Try Out this code,

Add this extension

extension Array where Element: Codable {

public var toData: Data {
let encoder = JSONEncoder()
do {
return try encoder.encode(self)
}
catch {
fatalError(error.localizedDescription)
}
}

public var toJson: String? {
return toData.toJson
}
}

extension Data {
// Convert NSData to String
public var toJson : String? {
return String(data: self, encoding: String.Encoding.utf8)
}
}

You web API Parameters like

let parameters: [String : Any] = [
"paymenttype":"debitcard",
"coupon":"",
"products":[["pid":"72","qnty":"1"],["pid":"4","qnty":"1"],["pid":"3","qnty":"1"]].toJson ?? "[]",
"grandtotal":"71499.52",
"discount":"",
"itemtotalval":"69417.0",
"cgst":"1041.26",
"comment":"sss",
"sgst":"1041.26",
"billingaddress":[["bfname":"debdeep nandy","bmobilenumber":"9875463215","bpincode":"823691" , "baddress":"kolkata","bcity":"kolkata","bstate":"West Bengal","bcountry":"india","bemail":"dev@gmail.com"]].toJson ?? "[]",
"shippingaddress":[["sfname":"debdeep nandy","smobilenumber":"9875463215","spincode":"823691","saddress":"kolkata","scity":"kolkata","sstate":"West Bengal","scountry":"india","semail":"india"]].toJson ?? "[]",
"user_id":1
]

And Your else Part is

else {
print("Malformed data received from fetchAllRooms service")
debugPrint(String(data: response.data!, encoding: String.Encoding.utf8))
//Print out our data
return
}

Sample Image

Note: in Alamofire parameter Pass Array or Dictionary value using JSON string format then this is worked.

Alamofire returns different result from what is expected

It seems it was really a cache issue. Following this solution, we could do something like this:

 var req = URLRequest(url: URL(string: Constants.ENDPOINT_GET_PROF_CALENDAR)!)
req.httpMethod = "GET"
req.setValue("application/json", forHTTPHeaderField: "Content-Type")
req.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

Alamofire.request(req).validate().responseJSON { response in
if response.result.isSuccess {
let rawResult = JSON(response.result.value!)
self.parseResponse(json: rawResult)
}else{
print("Error getting appointments")
}
}

Alamofire sending a request to an API 'NSInvalidArgumentException'

You need to make values a string not double

let address: Parameters = [
"location" : addressField.text!,
"locationLat" :"\(pickedLocationLat)",
"locationLong" :"\(pickedLocationLong)"
]

Swift 4.2 - Alamofire all of a sudden not working

Did you know you can parse JSON super easily with Swift 4.2?
I used it recently with a dialling code table view - the data was a local JSON file:

    struct Countries: Codable {
let countries: [Country]
}

struct Country: Codable {
let code: Int
let name: String
let flagImage: String
}

enum CodingKeys: String, CodingKey {
case code
case name
case flagImage
}

class CountryListVC: UITableViewController {

func loadJSON() {

if let path = Bundle.main.path(forResource: "countryDiallingCodes", ofType: "json") {

do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
let jsonObj = try JSONDecoder().decode(Countries.self, from: data)
print("JSON Object: ", jsonObj)
countries = jsonObj.countries

} catch let error {
print (error)
}
} else {
print ("Error in path")
}
}


Related Topics



Leave a reply



Submit