Alamofire: обработка ошибок кода состояния HTTP 401 в Swift - PullRequest
0 голосов
/ 24 марта 2020

На самом деле мне нужно обработать статус http 401 по истечении срока действия токена. Я использую Alamofire в основном class DataProvider : NSObject, а в viewControllers я использую функцию обратного вызова для каждого сервиса.

  • Как я могу обработать response.statusCode в функции Alamofire или мне нужно обрабатывать в каждой функции обратного вызова 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 голосов
/ 24 марта 2020

API Alamofire validate и RequestInterceptor предназначены для этого случая использования. Чтобы реализовать это, вам нужно сделать несколько вещей:

  1. Добавить вызов validate к вашим запросам. Это приведет к ошибке, которая вызовет автоматическое повторение Alamofire c. Вы уже делаете это, и это хорошо.
  2. Реализация RequestInterceptor. Он состоит из двух частей:
    1. Чтобы добавить свой токен в запрос, реализуйте функцию adapt. Это может изменить ваш запрос до того, как он пройдет по сети, и позволит вам добавить свой токен в запрос после повторной попытки.
    2. Чтобы вызвать повторную попытку, используйте функцию retry. В этом вам нужно будет проверить ошибку, которая появляется, чтобы определить, нужно ли вам повторить попытку. Если это так, вы можете позвонить в службу токенов, чтобы получить новый и вызвать повторную попытку.
  3. Когда запрос повторяется, он снова адаптирует свой URLRequest, добавив действительный токен, который должен разрешить ваш запрос.

Подробнее о RequestInterceptor s можно прочитать в нашей документации .

0 голосов
/ 24 марта 2020

Добро пожаловать в StackOverflow!

Один из подходов для более общего подхода - добавить EventMonitor к вашей сессии. Таким образом, вы можете проверить все ответы одновременно и, возможно, вызвать обратный вызов или локальное уведомление для распространения этого состояния обратно в пользовательский интерфейс:

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