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传递给getAccessKeysomethingNeedingAccessKey的其余部分,那么你可以确定你的accessKey总是有效的。 如果你需要另外一个需要accessKey函数,只需要用写入somethingNeedingAccessKey来写。

 public func somethingElse() { getAccessKey { (accessKey, error) in if accessKey != nil { // Do something else with accessKey } else { // Handle nil accessKey / error here } } }