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 ,这是因为请求可能需要一段时间,所以闭包直到返回后才会执行。将 return 移至闭包的建议解决方案对我来说不起作用,编译器只是大喊大叫(在 (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 表单,因此也许您需要它来用于将来在其他功能中发出的请求。

在这种情况下,您可以执行以下操作:

注意:异步编程是一个很大的话题;这里涉及的内容太多了。这只是您如何处理从异步请求返回的数据的一个示例。

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/38138804/

相关文章:

ios - 如何从类中为 EnvironmentObject 设置值?

ios - 如何在 Swift 中使用 firstIndex 查找所有结果

swift - 我无法获得 WatchConnectivity 的 session :didRecieveMessage: to be called

ios - 在 Swift 5、iOS 14 中编码可编码结构时出现 NSJSONSerialization 错误 : Invalid top-level type in JSON write

ios - 沿其中心旋转 SKShapeNode

ios - dyld : Library not loaded: @rpath/Alamofire. framework/Alamofire 原因:找不到图像

ios - Alamofire 获取带参数数据的问题

ios - "No such module ' Alamofire '"Xcode 无法识别 Alamofire 框架

swift - 将值附加到 [String : AnyObject] or [String : String]

ios - Swift 4 - 使用 httpbody 的 Alamofire 发布请求