Использование токена обновления для получения нового токена авторизации и повторения неудачного вызова API - PullRequest
0 голосов
/ 24 сентября 2019

У меня общий вопрос об использовании токенов в swift для выполнения вызовов API.Токен авторизации, который необходим для выполнения вызовов API, истекает каждый час, поэтому мне нужен способ обработки этого в обобщенном виде для нескольких вызовов API.

Я столкнулся с проблемой, когда, если я получаю ошибку 401, я вызываю функцию, чтобы использовать токен обновления, чтобы получить новый токен авторизации, и я хотел бы повторно вызвать исходную функцию, которая получила ошибку 401.

Например:

Если я получаю ошибку 401 при звонке getDetails(), я хочу позвонить на getNewAuthToken(), а после получения нового токена обновления я хочу снова вызвать getDetails(),

Я хочу сделать это так, чтобы, если я вызываю любую функцию getX() и получаю ошибку 401, она вызывает getNewAuthToken(), а затем снова вызывает исходную функцию getX()

Каков наилучший способ подойти к этому без использования каких-либо внешних библиотек и т. Д. Наилучшим ли способом будет использование некой функции обратного вызова?

Я предоставил общий код, который реализовывал, но, как вы можетевидите, когда я получаю ошибку 401, она вызывает функцию getNewAuthToken(), но исходная функция больше не вызывается.Как можно изменить этот код, чтобы он вел себя как нужно?

import UIKit
import Combine

@Published var details: Details = nil

func getNewAuthToken(){
// here I request a token using the refresh token

}

func getDetails(){
    self.getCurrentDetails{ details in
        DispatchQueue.main.async {
             self.details = details
        }
    }
}

func getCurrentDetails(_ completionHandler: @escaping (Details) -> ()) {
    let url = "https://api.xxx.com/details"
    guard let detailsURL = URL(string: url) else{
        fatalError("URL not valid")
    }
    let authtoken = keychain.get("authtoken") ?? ""
    var request = URLRequest(url: detailsURL)
    request.httpMethod = "GET"
    request.addValue("Bearer \(authtoken)", forHTTPHeaderField: "Authorization")
    let session = URLSession.shared

    let task = session.dataTask(with: request){
        data, response, error in
        let httpResponse = response as? HTTPURLResponse
        // I request a new token
        if(httpResponse?.statusCode == 401){
            print("401")
            self.getNewAuthToken()
            return
        }
        do {
            if(httpResponse?.statusCode != 200){
                return
            }
            let decoder = JSONDecoder()
            let details = try decoder.decode(Details.self, from:
                data!)
            completionHandler(details)

        } catch  let error2{
            print(error2)
        }
    }
    task.resume()
}

1 Ответ

0 голосов
/ 24 сентября 2019

Я не думаю, что вам нужно разделить функцию типа "getX ()", чтобы справиться с этим.Все, что вам нужно, это обработчик завершения.

func getNewAuthToken(completionHandler: () -> Void) {
// here I request a token using the refresh token
    completionHandler()
}

func someNetworkCall() {
    getNewAuthToken {
        someNetworkCall()
    }
}
...