Reputation: 149
Actually I need to handle http status 401 on token expiration. I am using Alamofire in a main class DataProvider : NSObject
and in viewControllers I am using callback function for every service.
Main purpose is once token expired it will auto navigate to LoginViewController
Alamofire Function: 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 Callback - 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
}
Upvotes: 2
Views: 2311
Reputation: 12770
Alamofire's validate
and RequestInterceptor
APIs are designed for this use case. To implement it, you need to do a few things:
validate
call to your requests. This will produce an error that will trigger Alamofire's automatic retry. You're already doing this, which is good.RequestInterceptor
. This has two parts:
adapt
function. This can modify your request before it goes over the network and allows you to add your token to the request after retry. retry
function. In this you'll need to check the error that comes in to determine whether you need to retry. If it is, you can make a call to your token service to get a new one and trigger retry.URLRequest
again, adding the valid token, which should allow your request to succeed.You can read more about RequestInterceptor
s in our documentation.
Upvotes: 2
Reputation: 8631
Welcome to StackOverflow!
One approach to handle this more generically, is to add an EventMonitor to your Session. This way you could check all responses at once, and perhaps trigger a callback or local notification to propagate this state back to the 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
}
}
}
Upvotes: 0