swift - AlamoFire GET api 请求未按预期工作

标签 swift alamofire

我正在努力学习如何使用 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
}

这会返回 nil,这是一个问题。从我读到的here ,这是因为请求可能需要一段时间,所以闭包直到返回后才会执行。将返回移动到闭包中的建议解决方案对我不起作用,编译器只是大喊大叫(在 (request,response,JSON,error) 之后添加 ->String给出“'String' 不是 void 的子类型”)。提供的其他解决方案也是如此。

有什么想法吗?即使一些与此问题无关的使用 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)
    }
}

然后像这样调用它(不要忘记错误处理):

siteInfo { (str, error) in
    if str != nil {
        // Use str value
    } else {
        // Handle error / nil value
    }
}

在您询问的评论中:

So how would you save the info you collect from the get request if you can only do stuff inside the closure and not effect objects outside of the closure? Also, how to keep track to know when the request has finished?

您可以从闭包内部将 get 请求的结果保存到类中的实例变量;闭包不会阻止您这样做。你从那里做什么实际上取决于你想用这些数据做什么。

举个例子怎么样?

因为看起来您正在获取获取请求的访问 key 表单,也许您需要它来处理 future 在其他功能中提出的请求。

在这种情况下,您可以这样做:

注意:异步编程是一个很大的话题;太多了,无法在这里介绍。这只是您可以如何处理从异步请求返回的数据的一个示例。

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() 将触发获取访问 key 的请求。之后对 somethingNeedingAccessKey() 的任何调用都将使用已存储在 self._accessKey 中的值。如果您在传递给 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
        }
    }
}

关于swift - AlamoFire GET api 请求未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25901460/

相关文章:

ios - Alamofire 4.0.0 : [String:String] is not convertible to [String : Any] & Request is ambiguous without more context

Swift:将一致的对象实例传递给泛型方法

ios - 如何在 NSURL 字符串中包含大括号?

swift - 在 Swift 中使用 String 的 enumerateLines 函数

ios - 如何将值附加到模型类

ios - 在 ios 中使用 Alamofire 在 collectionView 中显示图像

iOS菜单标题到导航栏标题动画

arrays - Swift 中的 elementsEqual 和 '==' 有什么区别?

swift - 错误 : Extra parameter in request i used Swift 4. 为什么我必须传递类型为 [String : Any]? 的参数

swift - Alamofire 的格式化字典