Home > OS >  log-in after checking the specific response from the API-POST request
log-in after checking the specific response from the API-POST request

Time:04-20

I am having problems with POST request function I made, The problem is that I don't know how to use that specific response of StatusCode that comes after validating a user, I made the function that sets-up the POST request but now I need to make the statement to check if the StatusCode is for example 0 the user gets logged in if its 1 it shows error.

My POST request:

func signInToAccount(username: String, password: String, completion: @escaping ([String: Any]?, Error?) -> Void) {
    
    let parameters = ["User": username, "Password": password]
    
    let url = URL(string: "https://randomurl/Signin")!
    
    let session = URLSession.shared
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
    } catch let error {
        print(error.localizedDescription)
        completion(nil, error)
    }
    
    request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
    
    let task = session.dataTask(with: request, completionHandler: { data, response, error in
        
        guard error == nil else {
            completion(nil, error)
            return
        }
        
        guard let data = data else {
            completion(nil, NSError(domain: "dataNilError", code: -100001, userInfo: nil))
            return
        }
        
        do {
            guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else {
                completion(nil, NSError(domain: "invalidJSONTypeError", code: -100009, userInfo: nil))
                return
            }
            print(json)
            completion(json, nil)
        } catch let error {
            print(error.localizedDescription)
            completion(nil, error)
        }
    })
    
    task.resume()
}

My sign-in button sender of sign-in viewController:

@IBAction func signInSegueToDashboard(_ sender: Any) {
    
    APICallerPOST.shared.signInToAccount(username: "admin", password: "admin123") { (result, error) in
        if let result = result {
            print("success: \(result)")
        } else if let error = error {
            print("error: \(error.localizedDescription)")
        }
    
        self.activityLoaderSignIn.startAnimating()
    
    guard let mainTabBarController = self.storyboard?.instantiateViewController(withIdentifier: "mainTabBarController") else {
        return
    }
    
    Timer.scheduledTimer(withTimeInterval: 2, repeats: false) {_ in
        
        self.activityLoaderSignIn.stopAnimating()
        mainTabBarController.modalPresentationStyle = .custom
        self.present(mainTabBarController, animated: true, completion: nil)
    }
  }
}

Now the problem is here: I don't know how to implement a proper way of logging-in, I need for example the if statement to check for the StatusCode if its 0 then the rest of code executed and to the dashboard if its error then show the error.

APICallerPOST.shared.signInToAccount(username: "admin", password: "admin123") { (result, error) in
        if let result = result {
            print("success: \(result)")
        } else if let error = error {
            print("error: \(error.localizedDescription)")
        }

The response that comes from the POST request:

{
"StatusCode": 0,
"Result": {
    "First": "admin",
    "Last": "admin123",
    "CompleteName": "admin admin123",
    "PhoneNumber": " 000 (00) 000-000",
    "Email": "[email protected]",
    "IsConnectedToCustomer": true,
    "Token": "a3311cc231994f34bfjksadf82f7a4djska3",
    "TokenExpireDate": "2023-05-19T13:49:15.383"
    }
}

Thanks in advance for those who contribute to help on this specific topic, And to all the newcomers this post will help a lot if the correct answer is found.

CodePudding user response:

Create a decodable struct which holds your server's response

struct SignInResponse: Decodable {
    struct SignInResult: Decodable {
        let First: String
        let Last: String
        let CompleteName: String
        let PhoneNumber: String
        let Email: String
        let IsConnectedToCustomer: Bool
        let Token: String
        let TokenExpireDate: String
    }

    let Result: SignInResult?
    let StatusCode: Int
}

IMPORTANT: This requires that your server either responds with an Result object as you have posted OR (when login failed) with "Result": null or with no Result object at all. But not an empty string or something like that.

Then modify the completion closure definition of your signInToAccount function to

func signInToAccount(username: String, password: String, completion: @escaping (SignInResponse?, Error?) -> Void) { ...

Inside this function, use a JSONDecoder to decode the response from your server.

let decoder = JSONDecoder()
        
guard let json = try? decoder.decode(SignInResponse.self, from: data) else {
   completion(nil, NSError(domain: "invalidJSONTypeError", code: -100009, userInfo: nil))
   return
}
 
print(json)
completion(json, nil)

Now you can access the StatusCode property in your function call's closure.

signInToAccount (username: "admin", password: "admin123") { (result, error) in
    if let result = result {

        print ("StatusCode is", result.StatusCode)

        if let signInData = result.Result {
            print ("Complete name:", signInData.CompleteName)
        }

        print("success: \(result)")
    } else if let error = error {
        print("error: \(error.localizedDescription)")
    }
}
  • Related