How to make Login for user from Web API with SwiftUI?

Viewed 1241

I have a web API testing, just like this (you can't access it as it needs a vpn to the server): http://172.16.5.56:8081/User/SpecificUser/userEmail/userPassword

If I open the API with correct email and password correctly (http://172.16.5.56:8081/User/SpecificUser/testing@testing.com/123123), It will give the user detail like this.

[   {
    "USERNAME": "ThisIsTestApp",
    "EMAIL": "testing@testing.com",
    "FULL_NAME": "TestingTesting",
    "NO_TELEPON": "0",
    "PASSWORD": "123123",
    "ROLE": null,
    "DEALER_CODE": null,
    "ALAMAT": null,
    "IS_ACTIVATED": "1",
    "USER_TOKEN": "testingTOken",
    "VERSION_APPS": null   } ]

But if I enter the wrong email or password on the API link, it will give an empty array like this

[ ]

My question is, how to check if the user is exists in the database, by checking the email and password with the given API?

First case, If the user is exists in the database, by checking the email and password with the given API. the app then will store the user information and will stay until the user press the LogOut button

Second case, If the user is not exists in the database or [ ] then the app will ask user to put email and password correctly

I have no idea left what should I do next. Now I've been trying to make a login thing for a days, but still can't find a way to do it correctly. If anyone can help me out it will be very helpful to me as a newbie and in case I want to make another login view in the future.

1 Answers

The GeometryReader is unnecessary. Your question is unclear so I am assuming that you are asking how you can determine if the user is logged in or not and display the correct view accordingly. You can create a JSON or PLIST file and store it in one of your app's directories with the user's information so that you can determine if they are logged in or not. From there, you can update func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) of SceneDelegate as follows:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("User.plist")
    //Change this to whatever file URL you want to use

    if FileManager.fileExsists(at: url) {
        let userDetailView = UserDetailView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: UserDetailView())
            self.window = window
            window.makeKeyAndVisible()
        }
    }
    else {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: ContentView())
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}

The above code will open the UserDetailView if the user is logged in and a PLIST or JSON file has been stored for the user which can be used to retrieve their information. If the user is not logged in, it will open the ContentView which is where you seem to have your login page. I would suggest changing the ContentView to only have the TextFields necessary to collect the email and password or whatever other information you need to collect.

I really hope this answers your question, and I'm sorry if it doesn't because your question is a bit unclear on what specifically it's asking.

EDIT:

After clarification from the OP, here is the actual answer:

The database can be accessed through URLSession. URLSession is an Apple API built into Swift.Foundation.

You can do this using the following code:

First, it would be best if you could create a User struct that conforms to Codable:

struct User: Codable {
    //Add necessary variables based on the data returned from the API
}

You need to add each variable and make the variable's name exactly as the identifier that you get from the Web API's data. For example, for the EMAIL field of the JSON data, you would need to add a variable in the struct called EMAIL.

Then, you can check the API and determine if the user exists using the following code:

func login(email: String, password: String) {
    let request = URLRequest(url: URL(string: "http://172.16.5.56:8081/User/SpecificUser/\(email)/\(password)")!)
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        if error != nil {
            print(error!)
            return
        }
        if let response = response {
            print(response)
        }
        if let data = data {
            do {
                let user = try JSONDecoder().decode(User.self, from: data)
                //The database has been checked and the user is successfully authenticated. Continue with saving the user data or whatever you need to do.
            }
            catch {
                print("Could not decode the data. Error: \(error)")
            }
        }
    }
    task.resume()
}

This function accepts an email and password parameter that is then added to the URL in the format you specified. Then the URLRequest is performed and the code checks if there are any errors. If it does have an error it will return. Then, the code checks if the data received was nil. If it is not nil, it will try to decode it into the User struct from the JSON data received. If it fails to do so, it can be determined that the login information was probably incorrect.

Hope this helps and please let me know if any clarification is necessary.

Related