AlamoFire GET API请求无法按预期工作 [英] AlamoFire GET api request not working as expected

查看:214
本文介绍了AlamoFire GET API请求无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何使用AlamoFire,但遇到了麻烦。

I am trying to get learn how to use AlamoFire and I am having trouble.

到目前为止,我的方法如下:

My method so far is as follows:

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,这是一个问题。根据我在此处所读内容,这是因为请求可能需要一段时间,因此关闭不会直到返回后才执行。建议将返回值移入闭包的解决方案对我不起作用,编译器只会大喊大叫(在之后添加-> String (请求,响应,JSON,错误),它给出'String'不是void的子类型)。

This returns nil which is a problem. From what I have read here, this is because the request can take a while so the closure doesn't execute till after the return. The suggested solution of moving the return into the closure does not work for me and the compiler just yells (adding ->String after (request,response,JSON,error) which gives "'String' is not a subtype of void"). Same goes for the other solution provided.

有什么想法吗?甚至与AlamoFire无关的一些与此问题无关的源代码也将有所帮助。

Any ideas? Even some source code that is not related to this problem, that uses AlamoFire, would be helpful.

谢谢!

推荐答案

一种解决方法是将闭包(通常称为 completionHandler )传递给您的 siteInfo 函数,并在 Alamofire.request 的闭包内进行调用:

One way to handle this is to pass a closure (I usually call it a completionHandler) to your siteInfo function and call that inside Alamofire.request's closure:

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)
    }
}

然后这样称呼它(不要忘记错误处理):

Then call it like this (don't forget error handling):

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






在您要求的评论中:




In the comments you asked:


那么,如果在以下情况下如何保存从get请求中收集的信息:您
只能在闭包内执行操作,而不会影响
闭包外的对象?另外,如何跟踪知道何时完成请求

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请求的结果从闭包内部到类中的实例变量;没有什么可以阻止您这样做。您从那里所做的事情实际上取决于您想对这些数据进行什么处理。

You can save the result of the get request to an instance variable in your class from inside the closure; there's nothing about the closure stopping you from doing that. What you do from there really depends on, well, what you want to do with that data.

由于看起来您正在获取获取请求的访问密钥表格,也许您需要其他功能将来发出的请求。

Since it looks like you're getting an access key form that get request, maybe you need that for future requests made in other functions.

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

In that case, you can do something like this:

注意:异步编程是一个巨大的话题;太多了,无法涵盖在这里。这只是如何处理从异步请求中获取的数据的一个示例。

Note: Asynchronous programming is a huge topic; way too much to cover here. This is just one example of how you might handle the data you get back from your asynchronous request.

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 的其余工作,并将其传递给 getAccessKey ,则可以确保您的 accessKey 将始终有效。如果您需要另一个需要 accessKey 的功能,只需用编写 somethingNeedingAccessKey 的相同方式编写它即可。

With that setup, calling somethingNeedingAccessKey() the first time will trigger a request to get the access key. Any calls to somethingNeedingAccessKey() after that will use the value already stored in self._accessKey. If you do the rest of somethingNeedingAccessKey's work inside the closure being passed to getAccessKey, you can be sure that your accessKey will always be valid. If you need another function that needs accessKey, just write it the same way somethingNeedingAccessKey is written.

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

这篇关于AlamoFire GET API请求无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆