Here is a very simple Xcode Login Screen Example for you. A login option is one of the essential feature of almost any application. In the last tutorial about iOS Registration Form Example we learnt creating a user registration screen in iOS App using Swift. In this tutorial we will see how to create a login screen.
If you haven’t gone through the previous tutorial then you should go through that tutorial first as I will be using the same MySQL database here as well. So lets start.
Contents
Building Login API
First we will build our Login API. For this I am going to use the same project that we created in the last iOS Registration Form Tutorial.
- Come inside includes folder and add two new methods.
<?php /** * Created by PhpStorm. * User: Belal * Date: 04/02/17 * Time: 7:51 PM */ class DbOperation { private $conn; function __construct() { require_once dirname(__FILE__) . '/Constants.php'; require_once dirname(__FILE__) . '/DbConnect.php'; // opening db connection $db = new DbConnect(); $this->conn = $db->connect(); } /* * This method is added * We are taking username and password * and then verifying it from the database * */ public function userLogin($username, $pass) { $password = md5($pass); $stmt = $this->conn->prepare("SELECT id FROM users WHERE username = ? AND password = ?"); $stmt->bind_param("ss", $username, $password); $stmt->execute(); $stmt->store_result(); return $stmt->num_rows > 0; } /* * After the successful login we will call this method * this method will return the user data in an array * */ public function getUserByUsername($username) { $stmt = $this->conn->prepare("SELECT id, username, email, phone FROM users WHERE username = ?"); $stmt->bind_param("s", $username); $stmt->execute(); $stmt->bind_result($id, $uname, $email, $phone); $stmt->fetch(); $user = array(); $user['id'] = $id; $user['username'] = $uname; $user['email'] = $email; $user['phone'] = $phone; return $user; } public function createUser($username, $pass, $email, $name, $phone) { if (!$this->isUserExist($username, $email, $phone)) { $password = md5($pass); $stmt = $this->conn->prepare("INSERT INTO users (username, password, email, name, phone) VALUES (?, ?, ?, ?, ?)"); $stmt->bind_param("sssss", $username, $password, $email, $name, $phone); if ($stmt->execute()) { return USER_CREATED; } else { return USER_NOT_CREATED; } } else { return USER_ALREADY_EXIST; } } private function isUserExist($username, $email, $phone) { $stmt = $this->conn->prepare("SELECT id FROM users WHERE username = ? OR email = ? OR phone = ?"); $stmt->bind_param("sss", $username, $email, $phone); $stmt->execute(); $stmt->store_result(); return $stmt->num_rows > 0; } }
- Now come inside the v1 folder and create a new php file here named login.php.
<?php /** * Created by PhpStorm. * User: Belal * Date: 29/05/17 * Time: 8:39 PM */ require_once '../includes/DbOperation.php'; $response = array(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { if (isset($_POST['username']) && isset($_POST['password'])) { $db = new DbOperation(); if ($db->userLogin($_POST['username'], $_POST['password'])) { $response['error'] = false; $response['user'] = $db->getUserByUsername($_POST['username']); } else { $response['error'] = true; $response['message'] = 'Invalid username or password'; } } else { $response['error'] = true; $response['message'] = 'Parameters are missing'; } } else { $response['error'] = true; $response['message'] = "Request not allowed"; } echo json_encode($response);
Testing the API
Now we can use any REST Client to test the login.php, I am using POSTMAN here.
As you can see the API is working absolutely fine. Now lets move ahead on the Xcode Side.
Xcode Login Screen Example
- So create a new project and add alamofire to it. If you are confused in this step you can go through the previous tutorial (iOS Registration Form Example) to know the steps.
Creating Login ViewController
- Once your project is ready in Main.storyboard create the following interface.
- Also connect the views with your ViewController.swift file.
- Also give an Storyboard ID to your ViewController as shown in the below image.
Creating Profile ViewController
- Click on Main.storyboard and then go to Editor -> Embed In -> Navigation Controller.
- Now drag one more ViewController to your storyboard and design it as shown below. It is the Profile Screen.
- As you can see in the newly created Viewcontroller we have two labels and one button. Now we need to create a class for this ViewController.
- So create a new Swift file named ProfileViewController.swift and write the following code.
// // ProfileViewController.swift // XcodeLoginExample // // Created by Belal Khan on 01/06/17. // Copyright © 2017 Belal Khan. All rights reserved. // import UIKit class ProfileViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
- Now come back to storyboard and assign this class to the ViewController and also give this ViewController an storyboard id.
Making Login
- Now come inside ViewController.swift and write the following code.
// // ViewController.swift // XcodeLoginExample // // Created by Belal Khan on 29/05/17. // Copyright © 2017 Belal Khan. All rights reserved. // import UIKit import Alamofire class ViewController: UIViewController { //The login script url make sure to write the ip instead of localhost //you can get the ip using ifconfig command in terminal let URL_USER_LOGIN = "http://192.168.1.105/SimplifiediOS/v1/login.php" //the defaultvalues to store user data let defaultValues = UserDefaults.standard //the connected views //don't copy instead connect the views using assistant editor @IBOutlet weak var labelMessage: UILabel! @IBOutlet weak var textFieldUserName: UITextField! @IBOutlet weak var textFieldPassword: UITextField! //the button action function @IBAction func buttonLogin(_ sender: UIButton) { //getting the username and password let parameters: Parameters=[ "username":textFieldUserName.text!, "password":textFieldPassword.text! ] //making a post request Alamofire.request(URL_USER_LOGIN, method: .post, parameters: parameters).responseJSON { response in //printing response print(response) //getting the json value from the server if let result = response.result.value { let jsonData = result as! NSDictionary //if there is no error if(!(jsonData.value(forKey: "error") as! Bool)){ //getting the user from response let user = jsonData.value(forKey: "user") as! NSDictionary //getting user values let userId = user.value(forKey: "id") as! Int let userName = user.value(forKey: "username") as! String let userEmail = user.value(forKey: "email") as! String let userPhone = user.value(forKey: "phone") as! String //saving user values to defaults self.defaultValues.set(userId, forKey: "userid") self.defaultValues.set(userName, forKey: "username") self.defaultValues.set(userEmail, forKey: "useremail") self.defaultValues.set(userPhone, forKey: "userphone") //switching the screen let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewcontroller") as! ProfileViewController self.navigationController?.pushViewController(profileViewController, animated: true) self.dismiss(animated: false, completion: nil) }else{ //error message in case of invalid credential self.labelMessage.text = "Invalid username or password" } } } } override func viewDidLoad() { super.viewDidLoad() //hiding the navigation button let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: navigationController, action: nil) navigationItem.leftBarButtonItem = backButton // Do any additional setup after loading the view, typically from a nib. //if user is already logged in switching to profile screen if defaultValues.string(forKey: "username") != nil{ let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewcontroller") as! ProfileViewController self.navigationController?.pushViewController(profileViewController, animated: true) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
- Now come inside ProfileViewController.swift and write the following code.
// // ProfileViewController.swift // XcodeLoginExample // // Created by Belal Khan on 01/06/17. // Copyright © 2017 Belal Khan. All rights reserved. // import UIKit class ProfileViewController: UIViewController { //label again don't copy instead connect @IBOutlet weak var labelUserName: UILabel! //button @IBAction func buttonLogout(_ sender: UIButton) { //removing values from default UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) UserDefaults.standard.synchronize() //switching to login screen let loginViewController = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController self.navigationController?.pushViewController(loginViewController, animated: true) self.dismiss(animated: false, completion: nil) } override func viewDidLoad() { super.viewDidLoad() //hiding back button let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: navigationController, action: nil) navigationItem.leftBarButtonItem = backButton //getting user data from defaults let defaultValues = UserDefaults.standard if let name = defaultValues.string(forKey: "username"){ //setting the name to label labelUserName.text = name }else{ //send back to login view controller } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
- Now run the application.
- Bingo! It is working absolutely fine. If you are having troubles you can download my source code from the below given link.
[sociallocker] Xcode Login Screen Example Source Code [/sociallocker]
So thats all for Xcode Login Screen Example. If you are having some queries lets discuss it on the comments section. And please SHARE this post if you found it helpful. Thank You 🙂
Andrew says
Hello. Can you help me? When I try to run this application, before login I have an error FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 “Invalid value around character 0.” UserInfo={NSDebugDescription=Invalid value around character 0.}))
pab says
It’s simple, I have a login system. Everything’s fiel with the mysql code, but I can’t retrieve the value into my application. So my question is: How do I proceed to recuperate a variable into my application from a mysql. Thanks for your answer.
Yaga says
Hello, I have the same error as Andrew. When I change the responseJSON to responseString the debug console shows the JSON in the correct format. The results however returns “\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0{\”error\”:false,\”user\”:{\”id\”:6,\”email\”:\”a\”,\”first_name\”:\”a\”,\”last_name\”:\”a\”}}\0\0\0\0″ . Do you know what is causing all the blank data before and after the JSON? This is what is causing the error for me. Any help will be greatly appreciated!
Lun says
Cannot Login into Profile View
Lula says
You can not log in can they help?
Rizan says
How to keep it login went we close and re open the app??
Frankie says
Hi,
I keep getting error “Thread 1: signal SIGABRT” every time I try to run this project. Also, this is what displays, “reason: ‘Storyboard () doesn’t contain a view controller with identifier ‘ProfileViewcontroller.” Please help, I have run of ideas and things to try. Using Xcode Version 9.1 (9B55)
Andreas says
Hey.
Late reply, but if you haven’t figured this out yet, or someone else has this problem, there is a solution:
As the error says, Storyboard doesn’t contain a view controller with identifier ‘ProfileViewcontroller”.
Go to main.storyboard, and click on the Profile View Controller. Click the “View Controller” icon on top of it (the yellow circle with a white square).
Click on “Show Identity Inspector” and give the storyboard the ID of: ProfileViewController.
Then go to ViewController.swift and find:
let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: “ProfileViewcontroller”) as! ProfileViewController
change the identifier to ProfileViewController, or just replace it with the line below
let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: “ProfileViewController”) as! ProfileViewController
Also in the ViewDidLoad function, do the same thing.
let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: “ProfileViewcontroller”) as! ProfileViewController
to:
let profileViewController = self.storyboard?.instantiateViewController(withIdentifier: “ProfileViewController”) as! ProfileViewController
Save and run.
Oguz says
im getting {“error”:true,”message”:”Request not allowed”} please help. i did everything correct!
Andreas says
Check your login.php script. The server request method should be post, as the code below shows:
if ($_SERVER[‘REQUEST_METHOD’] == ‘POST’)
also, go to your ViewController.swift and make sure that Alamofire.request methos is set to .post:
Alamofire.request(URL_USER_LOGIN, method: .post, parameters: parameters).responseJSON
Andres says
Jason Response is a SUCCESS but the app wont switch views to profileViewController . , no error showing either , what would be the problem?
Michael says
Took a while to realise the class for DBConnect was in the register tutorial, but this worked great in my project! Thank you!
George says
What if a user has logged in in the app and then someone delete the user logged in from the database. How will the app know that the user is no more in the database and will automatically log out from the app?
Belal Khan says
This is very basic example, for this you need to generate a session, or token on each login, and everytime you need to check if the user is logged in or not you need to match that token from the server.
George Zoiade says
What if the user that is logged in the app will be deleted from the database? How will the app verify that is not in the database and automatically log him out?
David says
Extremely useful! Thanks for the tutorial. I’d also recommend checking out this Login Screen template written in Swift which has support for Facebook & Twitter Login as well as can be integrated with the PHP backend you’ve outlined in this article.