I am making url calls thru an API that I created using swift as follows:
class API { let apiEndPoint = "endpoint" let apiUrl:String! let consumerKey:String! let consumerSecret:String! var returnData = [:] init(){ self.apiUrl = "https://myurl.com/" self.consumerKey = "my consumer key" self.consumerSecret = "my consumer secret" } func getOrders() -> NSDictionary{ return makeCall("orders") } func makeCall(section:String) -> NSDictionary{ let params = ["consumer_key":"key", "consumer_secret":"secret"] Alamofire.request(.GET, "\(self.apiUrl)/\(self.apiEndPoint + section)", parameters: params) .authenticate(user: self.consumerKey, password: self.consumerSecret) .responseJSON { (request, response, data, error) -> Void in println("error \(request)") self.returnData = data! as NSDictionary } return self.returnData } }
I call this API in my UITableViewController
to populate the table with SwiftyJSON library. However my returnData
from the API is always empty. There is no problem with Alomofire calls as I can successfully retrieve value. My problem is how I am supposed to carry this data
over to my table view controller?
var api = API() api.getOrders() println(api.returnData) // returnData is empty
Alamofire is a networking library written in Swift. You use it to make HTTP(S) requests on iOS, macOS and other Apple platforms. For example, to post data to a web-based REST API or to download an image from a webserver. Alamofire has a convenient API built on top of URLSession (“URL Loading System”).
Alamofire makes developing networking layers easier, faster and much cleaner. Another great benefit of using it is that it can be studied and its code is available. This can help programmers because it's a well-written framework.
Alamofire is an HTTP networking library written in Swift. SwiftyJSON makes it easy to deal with JSON data in Swift. Steps to setup the CocoaPods. Open Terminal. CocoaPods runs on ruby so update your system.
As mattt points out, Alamofire is returning data asynchronously via a “completion handler” pattern, so you must do the same. You cannot just return
the value immediately, but you instead want to change your method to not return anything, but instead use a completion handler closure pattern.
Nowadays, that might look like:
func getOrders(completionHandler: @escaping (Result<[String: Any]>) -> Void) { performRequest("orders", completion: completionHandler) } func performRequest(_ section: String, completion: @escaping (Result<[String: Any]>) -> Void) { let url = baseURL.appendingPathComponent(section) let params = ["consumer_key": "key", "consumer_secret": "secret"] Alamofire.request(url, parameters: params) .authenticate(user: consumerKey, password: consumerSecret) .responseJSON { response in switch response.result { case .success(let value as [String: Any]): completion(.success(value)) case .failure(let error): completion(.failure(error)) default: fatalError("received non-dictionary JSON response") } } }
Then, when you want to call it, you use this completion
closure parameter (in trailing closure, if you want):
api.getOrders { result in switch result { case .failure(let error): print(error) case .success(let value): // use `value` here } } // but don't try to use the `error` or `value`, as the above closure // has not yet been called //
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With