iosswiftxcodealamofireswift3.2

How to refresh JWT token status Code 500 in Alamofire Swift


Thanks for have look on my question. I get into point. I have to refresh JWT token using Alamofire Swift. Token expire every 30mins so while I'm making POST or GET Request token may expired and hits error code (status code) 500. Then i have to recall refresh token API and get new token from server then again i have to call previous API back. My problem is how can i call back failed API after get new token. Hope can some one help for this with better solution. Thanks in advance.

current status.

API request method,

func statusStaffCheckInOut(completion: @escaping(Bool)->Void){

        guard let userID= userLoginModel.user?.id else{ return }
        guard let jwtToken = userLoginModel.jwt else{ return }

        let x_headers = ["x-authorization": "\(jwtToken)","id":"\(userID)"]

        Alamofire.request("\(BASE_MIDDLEWARE_URL)/url",method: .get, encoding: JSONEncoding.default , headers: x_headers).validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"]).responseJSON { response in
                // print("Request: \(String(describing: response.request))")
                // response serialization result
                if let json = response.result.value as? [String:Any]{
                    userLoginModel.staffcheckincheckout?.setValuesForKeys(json)
                    completion(true)
                 }else {
                    if let statusCode = response.response?.statusCode{
                        print("status code \(statusCode)")
                        if statusCode == 500{ ///Check 500 Error code
                            print("Status code ***\(500)***")
                            ///Refresh taken call
                            self.refreshJWTToken(trigeredURL: "url"){(response) in
                            }
                        }
                    }
                    completion(false)
                }
        }
    }

Refresh token Method:

//MARK:- Token Refresh
    func refreshJWTToken(trigeredURL: String,completion: @escaping([[String:Any]],Bool)->Void){

        guard let userID = userLoginModel.user?.id else{ return }

        let url = "\(BASE_MIDDLEWARE_URL)/url?id=\(userID)"

        Alamofire.request(url,method: .get, encoding: JSONEncoding.default).validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"]).responseJSON { response in
                if let json = response.result.value as? String{
                    userLoginModel.jwt = json
                    print("Refreshed JWT: \(json)")
                    completion([["Message":"Success"]],true)
                }else {
                    completion([["Message":"Faild"]],false)
                }
        }
    }

Solution

  • I've modified your request to accomodate your need.

    Enum :

    enum APIResult<T> {
    case success(T)
    case failure(NSError)
    

    }

    API request method :

    func statusStaffCheckInOut(callback: @escaping(APIResult<Void>) -> Void){
    
        guard let userID= userLoginModel.user?.id else{ return }
        guard let jwtToken = userLoginModel.jwt else{ return }
    
        let x_headers = ["x-authorization": "\(jwtToken)","id":"\(userID)"]
    
        Alamofire.request("\(BASE_MIDDLEWARE_URL)/url",method: .get, encoding: JSONEncoding.default , headers: x_headers).validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"]).responseJSON { response in
                // print("Request: \(String(describing: response.request))")
                // response serialization result
    
                if let json = response.result.value as? [String:Any]{
                    userLoginModel.staffcheckincheckout?.setValuesForKeys(json)
                    //                    completion(true)
                    callback(.success(()))
                }else {
                    if let statusCode = response.response?.statusCode{
                        print("status code \(statusCode)")
                        if statusCode == 500 { ///Check 500 Error code
                            print("Status code ***\(500)***")
                            ///Refresh token call
                            self.refreshJWTToken(trigeredURL: "url"){ result in
                                switch result {
                                case .success(_):
                                    self.statusStaffCheckInOut(){ result in
                                        switch result {
                                        case .success(()) : callback(.success(()))
                                        case let .failure(error): callback(.failure(error))
                                        }
                                    }
                                case let .failure(error):
                                    callback(.failure(error))
                                }
                            }
                        }
                    }
                    callback(.failure(NSError(domain: "Error", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid authorization"])))
                }
    
        }
    }
    

    Refresh Token method:

    //MARK:- Token Refresh
    func refreshJWTToken(trigeredURL: String,callback: @escaping(APIResult<Void>) -> Void){
    
        guard let userID = userLoginModel.user?.id else{ return }
    
        let url = "\(BASE_MIDDLEWARE_URL)/url?id=\(userID)"
    
        Alamofire.request(url,method: .get, encoding: JSONEncoding.default).validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"]).responseJSON { result in
                switch response.result {
                case let .success(value):
                    if let json = value as? String{
                        userLoginModel.jwt = json
                        print("Refreshed JWT: \(json)")
                        callback(.success(()))
                    }else {
                        callback(.failure(NSError(domain: "Error", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid authorization"])))
                    }
                case let .failure(error):
                    callback(.failure(NSError(domain: "Error", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid authorization"])))
                }
        }
    }
    

    I'm using generic return for the api result. You can pass anything in success callback.