刷新访问令牌后重试旧请求

时间:2019-06-26 06:48:28

标签: swift asynchronous callback access-token

我正在通过UI执行网络任务。当 accessToken 过期时,响应将获得状态代码 499 。我需要刷新 accessToken 并使用请求对象执行相同的请求。如果第二个请求成功(带有新的访问令牌),则UI应获得成功响应。否则失败了。

//********************* UI Side ****************************
/// Fetching Topic list
private func loadTopics() {
    try! SDKCore.getInstance().getKbService().fetchKbTopics { (result) in
        switch result {
        case .success(let topics):
            self.topicList = topics
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        case .failed(let error):
            print(error.localizedDescription)
        }
    }
}


//********************* Service Class Example ****************************
public func fetchKbTopics(completionHandler: @escaping (ResultModel<[KBTopic], Error>) -> Void) {
    let request = GetKBTopics()

    Networking.shared.performRequest(request) { (response) in
        switch response {
        case .success(let response):
            do {
                let decoder = JSONDecoder()
                let result = try decoder.decode(GetKBTopics.Response.self, from: response.data!)
                completionHandler(.success(result))

            } catch let error {
                completionHandler(.failed(.unexpectedResponse(error)))
            }
        case .failed(let error):
            completionHandler(.failed(error))
        }
    }
}


//********************* Network Adapter ****************************
func performRequest<T: RequestModel>(_ request: T, completionHandler: @escaping (ResultModel<DataResponse<Any>, Error>) -> Void) {

    let adapterRequest = request.buildURLRequest()
    Alamofire.request(adapterRequest)
        .responseJSON { (response) in

            let statusCode = response.response?.statusCode ?? -1
            switch statusCode {
            case 200...299:
                completionHandler(.success(response))
            case 499:
                // Access token expired
                AuthService.tokenRefresh(completionHandler: { (result) in
                    switch result {
                    case .success(let resp):
                        self.performRequest(request) { (response) in }
                    case .failed( _):
                        completionHandler(.failed(.unexpectedResponse("Unexpected Response")))
                    }
                })
            default:
                completionHandler(.failed(.unexpectedResponse("Unexpected Response")))
            }
    }
}

1 个答案:

答案 0 :(得分:0)

幸运的是我找到了答案:-

//********************* UI Side ****************************
/// Fetching Topic list
private func loadTopics() {
    try! SDKCore.getInstance().getKbService().fetchKbTopics { (result) in
        switch result {
        case .success(let topics):
            self.topicList = topics
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        case .failed(let error):
            print(error.localizedDescription)
        }
    }
}


//********************* Service Class Example ****************************
public func fetchKbTopics(completionHandler: @escaping (ResultModel<[KBTopic], Error>) -> Void) {
    let request = GetKBTopics()

    Networking.shared.performRequest(request) { (response) in
        switch response {
        case .success(let response):
            do {
                let decoder = JSONDecoder()
                let result = try decoder.decode(GetKBTopics.Response.self, from: response.data!)
                completionHandler(.success(result))

            } catch let error {
                completionHandler(.failed(.unexpectedResponse(error)))
            }
        case .failed(let error):
            completionHandler(.failed(error))
        }
    }
}


//********************* Network Adapter ****************************
   func performRequest<T: RequestModel>(_ request: T, completionHandler: @escaping (ResultModel<Data, SDKError>) -> Void) {

        let adapterRequest = request.buildURLRequest()
        Alamofire.request(adapterRequest)
            .responseJSON { responseObject in

                switch statusCode {
                case 200...299:
                    completionHandler(.success(response))
                case 499:
                    print("*******************ACCESS TOKEN EXPIRED************************")
                    self.refreshAuthToken(request) { status in
                        if status {
                            print("*******************ACCESS TOKEN RENEWED************************")
                            self.performRequest(request) { result in
                                switch result {
                                case .success(let response2):
                                    completionHandler(.success(response2))
                                case .failed(let error2):
                                    completionHandler(.failed(.unexpectedResponse(error2.localizedDescription)))
                                }
                            }
                        }
                        else {
                            print("*******************REFRESH TOKEN EXPIRED***********************")
                            completionHandler(.failed(.tokenExpired("Your session expired.")))
                        }
                    }
                default:
                    completionHandler(.failed(.unexpectedResponse("Unexpected Response")))
                }
        }
    }

    //****************** Service class for token refresh *************************
    // Calling the same performRequest() method with current refresh token. 
    // onSuccess saving token in local and return success handler
    private func refreshAuthToken<T: RequestModel>(_ request: T, completionHandler: @escaping (Bool) -> Void) {
        AuthService().tokenRefresh { result in
            switch result {
            case .success:
                // New tokens saved on AuthService().tokenRefresh func internally.
                completionHandler(true)
            case .failed:
                completionHandler(false)
            }
        }
    }