首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阿拉莫火:全球范围内如何处理401?

阿拉莫火:全球范围内如何处理401?
EN

Stack Overflow用户
提问于 2016-03-17 13:37:32
回答 1查看 3.8K关注 0票数 10

我正在尝试构建一个类来管理我的项目的网络调用。到目前为止,我的意思是在全球范围内处理错误,一切都很好。我创建了两个函数: post请求postRequest(:_)和get请求getRequests(:_)。Datamaker函数返回数据,如URL、参数、标头等,数据分离函数用于解析响应数据,最后是一个用于解决错误的函数,称为errorHandler()

当我调用请求函数之一时,我给出了一个参数来帮助函数发出它应该发出的请求。在该函数中,它首先调用数据制造者来获取数据,然后使用Alamofire进行请求,如果请求成功,则调用dataparser和onSuccess(data:)闭包,如果不是,则调用errorHandler(statusCode:)onFailure(message:)闭包。

我在errorHandler中放置了一个开关块,并给出了它的参数statusCode。在case 401中,我调用了Token().refresh(),在它的完成中,它被称为errorHanlder的完成。在postRequest/errorHandler的完成块中,我再次用相同的参数调用postRequest。它没有工作。我不知道为什么,它每次都进入无限循环,并连续地发出请求。

因此,我决定尝试cnoonAuthorizationManager类(可以在这个链接中找到;Alamofire : How to handle errors globally)。我稍微修改了它(添加了一个新的参数作为标题,并将NetworkSuccessHandler的类型更改为NSData )。

代码语言:javascript
复制
public class AuthorizationManager: Manager {
    public typealias NetworkSuccessHandler = (NSData?) -> Void
    public typealias NetworkFailureHandler = (NSHTTPURLResponse?, AnyObject?, NSError) -> Void

    private typealias CachedTask = (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void

    private var cachedTasks = Array<CachedTask>()
    private var isRefreshing = false

    public func startRequest(
        method method: Alamofire.Method,
        URLString: URLStringConvertible,
        parameters: [String: AnyObject]?,
        encoding: ParameterEncoding,
        headers: [String:String]?,
        success: NetworkSuccessHandler?,
        failure: NetworkFailureHandler?) -> Request?
        {
            let cachedTask: CachedTask = { [weak self] URLResponse, data, error in
                guard let strongSelf = self else { return }

                if let error = error {
                    failure?(URLResponse, data, error)
                } else {
                    strongSelf.startRequest(
                        method: method,
                        URLString: URLString,
                        parameters: parameters,
                        encoding: encoding,
                        headers:  headers,
                        success: success,
                        failure: failure
                    )
                }
            }

            if self.isRefreshing {
                self.cachedTasks.append(cachedTask)
                return nil
            }

            // Append your auth tokens here to your parameters

            let request = self.request(method, URLString, parameters: parameters, encoding: encoding, headers:  headers)

            request.response { [weak self] request, response, data, error in
                guard let strongSelf = self else { return }

                if let response = response where response.statusCode == 401 {
                    strongSelf.cachedTasks.append(cachedTask)
                    strongSelf.refreshTokens()
                    return
                }

                if let error = error {
                    failure?(response, data, error)
                } else {
                    success?(data)
                }
            }

            return request
    }

    func refreshTokens() {
        self.isRefreshing = true

            // Make the refresh call and run the following in the success closure to restart the cached tasks
        Token().refresh { () -> () in
            let cachedTaskCopy = self.cachedTasks
            self.cachedTasks.removeAll()
            cachedTaskCopy.map { $0(nil, nil, nil) }
            self.isRefreshing = false
        }
    }
}

它在我的postRequest中叫做:

代码语言:javascript
复制
func postRequest(requestType: postRequestType, additionalParameters: [String]?, onSuccess: onSuccessRequest = {_ in }, onFailure: onFailureRequest = {_ in }){
    print("post")
    let requestData = returnStaticDataForPostRequest(requestType, additionalParameters: additionalParameters)
    let Manager = AuthorizationManager()
    Manager.startRequest(method: .POST, URLString: requestData.0, parameters: requestData.2, encoding: requestData.3, headers: requestData.1, success: { (data) -> Void in
        print("Manager")
        let json = JSON(data: data!)
        print(json)
        dataParserForPostRequests(json, parseForWhat: requestType)
        onSuccess(json: json)
        }) { (response, message, error) -> Void in
            print(error)
    }

}

以及postRequestsViewController中的使用:

代码语言:javascript
复制
postRequest(.LOGIN, additionalParameters: ["asdasd", "asdasd"], onSuccess: { (json) -> () in
            print(">>>login_try_succeeded")        
            self.performSegueWithIdentifier("LoginToMain", sender: self)
            }) { (errorCode) -> () in
            print(">>>login_try_failed(\(errorCode))")
        }

这是目前的状况。当我运行代码并尝试登录时,AuthorizationManager不起作用。它只是印出来的;

代码语言:javascript
复制
post

最后,我不知道这是否相关,但这一行有黄色警告:

代码语言:javascript
复制
cachedTaskCopy.map { $0(nil, nil, nil) }

"Result of call to 'map' is unused"

总之,我需要弄清楚我如何处理401系统,我知道如何以与此不同的方式使用AuthorizationManager

编辑

我尝试从ViewController直接运行这段代码,但它根本不起作用。就像代码是看不见的。

代码语言:javascript
复制
AuthorizationManager().startRequest(method: .POST, URLString: NSURL(string: "http://server.url/token")!, parameters: ["":""], encoding: .JSON,headers: ["":""], success: { (data) -> Void in
            print(data)
            }) { (response, data, error) -> Void in
                print(error)
                print("asdasd")
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-27 01:47:09

在您的AuthorizationManager最初尝试发送请求之后,可能不会持久化。

通常,避免使用单例模式是一种很好的做法,但这并不是一个坏情况:

代码语言:javascript
复制
public class AuthorizationManager: Manager {
    static let shared = AuthorizationManager()
    // ...the rest of your class
}

在调用请求时,使用这个单例实例,而不是实例化一个新的AuthorizationManager,如

代码语言:javascript
复制
AuthorizationManager.shared.startRequest(method: .POST, ...etc...

我猜这可能就是问题所在,因为当您在这两种情况下创建AuthorizationManager时,都不会主动保留该对象。可以创建管理器,运行请求,然后在cachedTask之前甚至在完成处理之前释放管理器,在这种情况下,您的guard let strongSelf = self else { return }将返回而不运行任何完成或cachedTasks。

希望这能帮上忙。如果这就是问题所在,那么单例解决方案应该非常简单。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36062200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档