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)")
}
}