处理此问题的一种方法是将闭包(我通常称其为 a completionHandler
)传递给您的siteInfo
函数并在内部Alamofire.request
的闭包中调用它:
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)
}
}
然后像这样调用它(不要忘记错误处理):
siteInfo { (str, error) in
if str != nil {
// Use str value
} else {
// Handle error / nil value
}
}
在你问的评论中:
那么,如果你只能在闭包内做事而不影响闭包外的对象,你将如何保存从 get 请求中收集的信息呢?此外,如何跟踪以了解请求何时完成?
您可以从闭包内部将 get 请求的结果保存到类中的实例变量中;关闭并没有阻止您这样做。你从那里做什么真的取决于你想用这些数据做什么。
举个例子怎么样?
由于看起来您正在获得一个获取请求的访问密钥表单,因此您可能需要它来处理其他功能中发出的未来请求。
在这种情况下,您可以执行以下操作:
注意:异步编程是一个巨大的话题;这里太多了。这只是您如何处理从异步请求返回的数据的一个示例。
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
}
}
}
}
使用该设置,第一次调用somethingNeedingAccessKey()
将触发获取访问密钥的请求。之后的任何调用somethingNeedingAccessKey()
都将使用已存储在self._accessKey
. 如果您somethingNeedingAccessKey
在传递给的闭包内完成 's 的其余工作getAccessKey
,您可以确定您的accessKey
将始终有效。如果您需要另一个需要的函数accessKey
,只需按照相同的方式somethingNeedingAccessKey
编写即可。
public func somethingElse() {
getAccessKey { (accessKey, error) in
if accessKey != nil {
// Do something else with accessKey
} else {
// Handle nil accessKey / error here
}
}
}