AlamoFire GET API请求不按预期工作
我正试图学习如何使用AlamoFire,我遇到了麻烦。
我的方法到目前为止如下:
func siteInfo()->String?{ var info:NSDictionary! var str:String! Alamofire.request(.GET, MY_API_END_POINT).responseJSON {(request, response, JSON, error) in info = JSON as NSDictionary str = info["access_key"] as String //return str } return str }
这返回零,这是一个问题。 从我在这里读到的,这是因为请求可能需要一段时间,所以封闭不会执行,直到返回。 build议的解决scheme将return移回到闭包中并不适用于我,编译器只是大喊(添加->String
(request,response,JSON,error)
,使得“'String'不是void的子types”)。 提供的其他解决scheme也一样。
有任何想法吗? 即使一些与这个问题无关的源代码,使用AlamoFire,将是有益的。
谢谢!
处理这个问题的一种方法是将一个闭包(我通常称之为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) } }
然后像这样调用它(不要忘记error handling):
siteInfo { (str, error) in if str != nil { // Use str value } else { // Handle error / nil value } }
在你问的评论中:
那么如果你只能在闭包内部做些东西而不影响闭包之外的对象,你将如何保存从获取请求中收集的信息? 另外,如何跟踪知道请求何时完成?
您可以将get请求的结果从closures中保存到类中的实例variables中; closures阻止你这样做没有关系。 你从那里做的事实上取决于你想用这些数据做什么。
举个例子呢?
由于看起来您正在获取获取请求的访问密钥表单,所以您可能需要使用其他function的未来请求。
在这种情况下,你可以这样做:
注意:asynchronous编程是一个巨大的话题; 这里掩盖的方式太多了。 这只是您如何处理从asynchronous请求中获得的数据的一个示例。
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
的值。 如果你在闭getAccessKey
传递给getAccessKey
的somethingNeedingAccessKey
的其余部分,那么你可以确定你的accessKey
总是有效的。 如果你需要另外一个需要accessKey
函数,只需要用写入somethingNeedingAccessKey
来写。
public func somethingElse() { getAccessKey { (accessKey, error) in if accessKey != nil { // Do something else with accessKey } else { // Handle nil accessKey / error here } } }