Alamofire:快速处理401 HTTP状态代码错误

时间:2020-03-24 15:59:17

标签: ios swift alamofire http-status-codes http-status-code-401

实际上,我需要处理令牌到期时的http状态401。我在主要class DataProvider : NSObject中使用Alamofire,并且在viewControllers中为每个服务使用回调函数。

  • 如何在Alamofire函数中处理response.statusCode,或者在每个webService回调函数中都需要处理。请为我推荐最佳方法。

主要目的是令牌过期后,它将自动导航到LoginViewController

Alamofire函数:DataProvider NSObject Class

@objc private func getDataFromWeb(params:NSMutableDictionary,
                                callback:@escaping (_ success:Bool, _ result:Any?)->(Bool)) -> Void {
        var method = HTTPMethod.get
        var encoding = URLEncoding.default as ParameterEncoding
        if(params["Method"] as! String == "POST"){
            method = HTTPMethod.post
            encoding = Alamofire.JSONEncoding.default
        }

        var url: String!
        if (params["ServiceName"] as! String == "Function/Login") && method.rawValue == "POST" {

            url = (params["BaseURL"]!  as! String) + (params["ServiceName"]!  as! String)

        }

        if method.rawValue == "GET" {

            url = (params["BaseURL"]!  as! String) + (params["ServiceName"]!  as! String)

        } 

        var pr = params as! Dictionary<String, Any>
        pr["BaseURL"] = nil
        pr["ServiceName"] = nil
        pr["Method"] = nil
        if token == nil{ print("token nil!") }

        Alamofire.request(url,
                          method:method,
                          parameters:pr,
                          encoding:encoding,
                          headers:[ "Accept":"application/json", "Authorization":"Bearer \(token ?? "")"])
            .downloadProgress(closure: { (progress) in
            //progress closure

                print(progress)
            print("Done progress bar working \(self.progressdelegate as Any)")
            self.progressdelegate?.progress(fractionCompleted: progress.fractionCompleted)
            })
            .validate(statusCode: 200..<300)
            .response { response in
                 print(response.error?.localizedDescription)
                if(callback(response.data?.count != 0, response.data)){
                    self.saveDataToDB(params: params, result: response.data!)
                }else{

                }

        }


    }

WebService回调-ViewController

func RequestData() {

        DataProvider.main.serviceGetFirmalar(callback: {success, result in
            do{
                if(success){
                    let decoder = JSONDecoder()
                    let response = try decoder.decode(ResponseData.self, from: result! as! Data)
                    self.AppData = response.firmList

                    self.tableView.reloadData()



                    return true
                }else{
                    return false
                }
            }catch let error {
                DataProvider.main.token = nil
                print(error as Any)
                return false
            }
        })
         // End of JSON


    }

2 个答案:

答案 0 :(得分:0)

欢迎使用StackOverflow!

一种更通用的处理方法是在会话中添加EventMonitor。这样,您可以一次检查所有响应,并可能触发回调或本地通知以将该状态传播回UI:

class ErrorResponseMonitor: EventMonitor {
    func requestDidResume(_ request: Request) { }

    func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) {
        if let httpResponse = response.response, httpResponse.statusCode == 401 {
            // Do stuff
        }
    }
}

答案 1 :(得分:0)

Alamofire的validateRequestInterceptor API是为此用例设计的。要实现它,您需要做一些事情:

  1. 向您的请求添加validate呼叫。这将产生一个错误,将触发Alamofire的自动重试。您已经在做,很好。
  2. 实施RequestInterceptor。这包括两个部分:
    1. 要将令牌添加到请求中,请实现adapt函数。这样可以在请求通过网络之前对其进行修改,并允许您在重试之后将令牌添加到请求中。
    2. 要触发重试,请实现retry函数。在这种情况下,您需要检查出现的错误以确定是否需要重试。如果是这样,您可以致电令牌服务以获取新的令牌服务并触发重试。
  3. 重试请求时,它将再次调整其URLRequest,并添加有效令牌,这将使您的请求成功。

您可以在our documentation中阅读有关RequestInterceptor的更多信息。

相关问题