ray*_*ohn 1 asynchronous ios swift alamofire
我无法异步从Alamofire请求中检索数据.
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
}
}
Run Code Online (Sandbox Code Playgroud)
输出print(book.title)是"",我明白这是因为print语句在请求返回之前运行.
如何book仅在使用请求中的数据实例化时才能返回实例?
Ene*_*nso 10
您遇到的问题是您正在调用异步方法并期望同步返回结果.执行代码时,getBook函数完成并在GET请求完成之前返回.
基本上,您有两种选择:
getBook方法更新为异步,并使用完成块/回调返回结果为此,必须在块/回调函数上返回结果.
class BookGetter {
static let instance = BookGetter()
func getBook(bookId: String, complete: (book: Book?, error: NSError?) -> Void) {
let rootUrl = "https://www.someusefulbookapi.com/bookid=?"
let url = rootUrl + bookId
var title = ""
Alamofire.request(.GET, url).response { request, response, data, error in
// TODO: You should check for network errors here
// and notify the calling function and end-user properly.
if error != nil {
complete(book: nil, error: error as? NSError)
return
}
let jsonDict = JSON(data: response.2!)
title = String(jsonDict["items"][0]["volumeInfo"]["title"])
let book = Book(title: title)
print(book.title)
complete(book: book, error: nil)
}
}
}
Run Code Online (Sandbox Code Playgroud)
如上面的代码所述,理想情况下,您应该处理回调响应中的错误(包括解析JSON时的异常).处理完毕后,您可以将回调参数更新为(book: Book?, error: NSError?) -> Void或类似,并检查book或error设置调用者函数.
要调用该函数,您需要传递一个块来处理响应:
BookGetter.instance.getBook("bookID") { (book, error) in
if error != nil {
// Show UIAlertView with error message (localizedDescription)
return
}
// Update User Interface with the book details
}
Run Code Online (Sandbox Code Playgroud)
如上所述,只有在后台线程上运行此代码时,这才是个好主意.可以阻止后台线程,但是在图形应用程序上阻塞主线程永远都不行,因为它会冻结用户界面.如果你不知道阻塞意味着什么,请使用选项#1.
class BookGetter {
static let instance = BookGetter()
func getBook(bookId: String) -> Book {
let rootUrl = "https://www.someusefulbookapi.com/bookid=?"
let url = rootUrl + bookId
var title = ""
let semaphore = dispatch_semaphore_create(0)
Alamofire.request(.GET, url).response { response in
let jsonDict = JSON(data: response.2!)
title = String(jsonDict["items"][0]["volumeInfo"]["title"])
dispatch_semaphore_signal(semaphore)
}
//Wait for the request to complete
while dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW) != 0 {
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 10))
}
let book = Book(title: title)
print(book.title)
return book
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1882 次 |
| 最近记录: |