I'm having trouble retrieving data from my Alamofire request asynchronously.
class BookGetter {
static let instance = BookGetter()
func getBook(bookId: String) -> Book {
let rootUrl = "https://www.someusefulbookapi.com/bookid=?"
let url = rootUrl + bookId
var title = ""
Alamofire.request(.GET, url).response { response in
let jsonDict = JSON(data: response.2!)
title = String(jsonDict["items"][0]["volumeInfo"]["title"])
}
let book = Book(title: title)
print(book.title)
return book
}
}
The output of print(book.title)
is ""
, and I understand this is because the print statement is running before the request returns.
How do I get the book
instance to be returned only when it is instantiated with the data from the request?
The problem you have is that you are calling an asynchronous method and expecting to return the result synchronously. When your code is executed, the
getBook
function completes and returns before even theGET
request has complete.Basically, you have two options:
getBook
method to be asynchronous and return the result with a completion block/callback1. Update your method to be asynchronous
To do this, you must return the result on a block/callback function.
As mentioned in the above code, ideally you should handle errors in the callback response (including exceptions while parsing the JSON). Once handled, you can update the callback parameters to
(book: Book?, error: NSError?) -> Void
or similar, and check forbook
orerror
to be set on the caller function.To call the function, you need to pass a block to handle the response:
2. Wait for the asynchronous call to complete
As mentioned above, this is a good idea only if you were running this code on a background thread. It is OK to block background threads, but it is never OK to block the main thread on a graphic application, as it will freeze the user interface. If you do not know what blocking means, please use the option #1.
You can use closures and return a
completionHandler
with your book like in the following way:And then you can call it like in the following way:
I hope this help you.