Hello I'm writing an ios swift 3 application to communicate with a website, the app after doing a number of things should return a type value of false or true, but it does not happen you can tell me where I'm wrong and how to correct the mistake!
VALUE RETURN at swift:
....response = Optional( { URL: "http://....myurl.php"}.....
SWIFT CODE:
let myUrl = URL(string: "http://....myurl.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "username=James&password=Bond";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(error)");
// return false
}
print("response = \(response)")
}
task.resume()
return 0;
PHP CODE:
include 'user.php';
$user = new User();
$username= $_REQUEST["username"];
$password = $_REQUEST["password"];
if($user->login($username,$password)==true){
echo json_encode("true");
}
else{
echo json_encode("false");
}
ERROR IMAGE:
You need to look into data and not response.
And maybe you should encapsulate your return value in your PHP code, like this for example:
if($user->login($username,$password)==true){
echo '{"success":true}';
}else{
echo '{"success":false}';
}
And then get the result in swift:
func login(request_completed:#escaping (_ succeded:Bool) -> ()) {
let myUrl=URL(string: "http://....myurl.php");
var request=URLRequest(url:myUrl!)
request.httpMethod="POST"
let postString = "username=James&password=Bond";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task=URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
guard data != nil else {
print("no data found")
request_completed(false)
return
}
do{
if let jsonData=try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary{
print(jsonData)
let success=jsonData.value(forKey: "success") as! Bool
if success{
print("login succeded")
request_completed(true)
return
}else{
print("login failed")
request_completed(false)
return
}
}else{
print("could not parse json")
request_completed(false)
}
}catch{
print("request failed")
request_completed(false)
}
})
task.resume()
}
Related
I am building an app, which has login page connected with my AWS server using PHP and MySQL, everything is working fine except that I have no idea how to save the PHP session within the app so the user can stay authenticated.
Part of my PHP code:
<?php
$session_start();
...
...
if($verify){
echo "Verfied";
$_SESSION["Authenticated"] = 1;
} else {
echo "Unverified";
$_SESSION["Authenticated"] = 0;
}
...
...
?>
Part of Swift code:
let url = URL(string: "http://localhost/login.php")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "username=\(username)&password=\(password)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)!
print("responseString = \(String(describing: responseString))")
DispatchQueue.main.async() {
if (responseString == "Vaild!") {
self.performSegue(withIdentifier: "MainPageSegue", sender: self)
} else {
self.errorLabel.text = "Invalid username or password."
}
}
}
task.resume()
How can I save the session within my app so the user stay authenticated?
Hello I have update my old swift app in the new version of swift 3, The code was connected to a php page by passing values in post and then returning a json message since I updated the app to swift 3 xcode me from the following errors, How can i fix these errors?
Error:
Swift Code:
let URL_SAVE_TEAM = "http://localhost/ios-login.php"
var email:String = "";
var password:String = "";
func PrintValue(){
// print(username);
//print(password);
}
func Login() -> Bool{
//created NSURL
let requestURL = NSURL(string: URL_SAVE_TEAM)
//creating NSMutableURLRequest
let request = NSMutableURLRequest(URL: requestURL)
//setting the method to post
request.HTTPMethod = "POST"
//getting values from text fields
//creating the post parameter by concatenating the keys and values from text field
let postParameters = "email="+email+"&password="+password;
//adding the parameters to request body
request.HTTPBody = postParameters.dataUsingEncoding(NSUTF8StringEncoding)
//creating a task to send the post request
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
if error != nil{
print("error is \(error)")
return;
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
//parsing the json
if let parseJSON = myJSON {
//creating a string
var msg : String!
//getting the json response
msg = parseJSON["message"] as! String?
//printing the response
print(msg)
}
} catch {
print(error)
}
}
//executing the task
task.resume()
return false;
}
Xcode Image of Error:
PHP CODE:
<?php
header('Content-Type: application/json');
$email= $_POST['email'];
$password = $_POST['password'];
$ris='Ti rispondo dal server zio';
echo json_encode($ris);
// echo "prova";
?>
I would write this more swiftly :)
func Login() -> Bool{
//created URL
guard let requestURL = URL(string: URL_SAVE_TEAM) else { return false }
//creating URLRequest
var request = URLRequest(url: requestURL)
//setting the method to post
request.httpMethod = "POST"
//getting values from text fields
//creating the post parameter by concatenating the keys and values from text field
let postParameters = "email=\(email)&password=\(password)"
//adding the parameters to request body
request.httpBody = postParameters.data(using: .utf8)
//creating a task to send the post request
let session = URLSession.shared
let task = session.dataTask(with: request) {
data, response, error in
guard error == nil else {
print("error is \(error!.localizedDescription)")
return
}
guard let data = data else {
print("No data was returned by the request!")
return
}
//parsing the response
do {
//converting resonse to NSDictionary
let myJSON = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? Dictionary<String, String?>
//parsing the json
guard let parseJSON = myJSON, let msg = parseJSON["message"] as? String else {
print("Error parsing data")
return
}
//printing the response
print(msg)
} catch {
print(error)
}
}
//executing the task
task.resume()
return false
}
You may think to add a completion handler to your function to handle the login success!
I am new to Swift and I am trying to create secure login with PHP in backend. But somewhere I am going wrong, my viewcontroller is segue to next view controller even though i Don't give login credential and getting following error in console:
Please help !!
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set
my code:
#IBAction func loginAuthentication(sender: UIButton) {
//declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid
let myUrl = NSURL(string: "my url");
var request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST"// Compose a query string
let postString = "username = \( NameTextField.text!) & password = \( passwortTextField.text!) ";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data , response , error in
if error != nil
{
let alert = UIAlertView()
alert.title = "Login Failed!"
alert.message = "Error: \(error)"
alert.delegate = self
alert.addButtonWithTitle("OK")
alert.show()
return
}
// You can print out response object
print("*****response = \(response)")
let responseString = NSString(data: data! , encoding: NSUTF8StringEncoding )
if ((responseString?.containsString("")) != nil) {
print("incorrect - try again")
let alert = UIAlertController(title: "Try Again", message: "Username or Password Incorrect", preferredStyle: .Alert)
let yesAction = UIAlertAction(title: "Nochmalversuchen", style: .Default) { (action) -> Void in
}
// Add Actions
alert.addAction(yesAction)
// Present Alert Controller
self.presentViewController(alert, animated: true, completion: nil)
}
else {
print("correct good")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("toPflegerProfile")
self.presentViewController(controller, animated: true, completion: nil)
}
print("*****response data = \(responseString)")
do {
//create json object from data
if let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? [String: Any] {
if let email = json["UserName"] as? String,
let password = json["passowrd"] as? String {
print ("Found User id: called \(email)")
}
}
} catch let error {
print(error)
}
}
task.resume()
}
php code :
<?php
require_once 'db.php';
$conn = connect();
if($conn)
{
if (isset($_GET['loginuser']))
{
//Getting post values
require_once 'getuserdata.php';
//1.Check if user is looged in
$loggedin = checkuserloggedin($username, $conn);
if ($loggedin)
{
$response['error']=true;
$response['message']='User is already logged in!';
}
else
{
//2.If not, insert pfleger
//Inserting log in values
if (insertuserdata($name,$username, $password, $gps, $logintime, $conn))
{
$response['error']=false;
$response['message']='Log Data added successfully';
}
else
{
$response['error']=true;
$response['message']='Could not add log in data';
}
}
}
else
{
$response['error']=true;
$response['message']='You are not authorized';
}
echo json_encode($response);
?>
use this
var request = URLRequest(url: URL(string: “url”)!)
request.httpMethod = "POST"
let userName = self.emailTextField.text!
let password = self.passtextField.text!
let postString = NSString(format: "emailId=%#&password=%action=%#",userName, password,”action name”)
request.httpBody = postString.data(using: String.Encoding.utf8.rawValue)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
do {
let jsonResults : NSDictionary = try JSONSerialization.jsonObject(with: data, options: [])as! NSDictionary
print("login json is ---%#",jsonResults)
let str = jsonResults.object(forKey: "status")as! String
if (str == "Success")
{
let newdic:NSDictionary = jsonResults.object(forKey: "response") as! NSDictionary
} catch {
// failure
print("Fetch failed: \((error as NSError).localizedDescription)")
}
}
task.resume()
So basically I have a login script on my server that returns a result depending on if the user credentials are correct or wrong, and I have an iOS App that sends data to that login script to return the correct or wrong result.
Here is the relevant part of my login page that shows the return code ($userDetails being the TRUE or FALSE check of correct or wrong credentials) :
$userDetails = $dao->getUserDetailsWithHashedPassword($email,$password);
if($userDetails===TRUE) {
$returnValue["status"] = "Success";
$returnValue["message"] = "User logged in !";
echo json_encode($returnValue);
} else {
$returnValue["status"] = "error";
$returnValue["message"] = "User not found";
echo json_encode($returnValue);
}
If anyone needs to see what that getUserDetailsWithHashedPassword() does, click here
Using Postman to test the HTTP POST, everything works fine, I get the correct result when posting email#email.com & testpassword in the body and using the correct Content-Type (application/x-www-form-urlencoded) :
{"status":"error","message":"User not found"}
Now my iOS is supposed to interpret this with this code :
#IBAction func loginButtonPressed(_ sender: AnyObject) {
let userEmail = emailLoginField.text
let userPassword = passwordLoginField.text
// Check for empty fields
if((userEmail?.isEmpty)! || (userPassword?.isEmpty)!) {
// Display alert message
displayMyAlertMessage(userMessage: "All fields are required");
return ;
}
// Send user data to server side
let myUrl = URL(string: "https://support.vincentsolutions.ca/userLogin.php");
var request = URLRequest(url:myUrl!);
request.httpMethod = "POST";
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let postString = "email=\(userEmail!)&password=\(userPassword!)";
request.httpBody = postString.data(using: String.Encoding.utf8);
URLSession.shared.dataTask(with: request, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) -> Void in
if error != nil {
print ("error=\(error)")
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
var resultValue = parseJSON["status"] as? String
print("result: \(resultValue)")
var isUserLoggedIn:Bool = false;
if(resultValue=="Success") {
// Login is successful
UserDefaults.standard.set(true, forKey: "isUserLoggedIn");
UserDefaults.standard.synchronize();
self.performSegue(withIdentifier: "loginSuccesful", sender: self)
}
var messageToDisplay:String = parseJSON["message"] as! String!;
if(!isUserLoggedIn) {
messageToDisplay = parseJSON["message"] as! String!;
}
DispatchQueue.main.async(execute: {
// Display alert message with confirmation.
var myAlert = UIAlertController(title: "Alert", message: messageToDisplay, preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ action in
self.dismiss(animated: true, completion: nil);
}
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil);
});
}
} catch let error as NSError {
print("An error occured: \(error)")
}
}).resume()
Now I'm getting this error when I run the code from the iOS App :
An error occured: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text
did not start with array or object and option to allow fragments not
set."
Does anyone see what could be wrong here ? I've tried looking for that error here on SO and on the internet but couldn't find anything related to my situation.
That is because the response you are receiving from the URL probably not in correct JSON format. I will suggest you to do 2 things -
Try to NSLog the data and response
Try this
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary
So I've got a few lines that will "login" to the web page, and they fetch the contents and print them to the console, but I can't figure out how to get the results out of the "task" and use them later on in the code.
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/mobilelogin.php")!)
request.HTTPMethod = "POST"
let username = email_input.text;
let password = password_input.text;
var postString = "username="
postString += username!
postString += "&password="
postString += password!
print(postString);
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
print(request.HTTPBody);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in guard error == nil && data != nil
else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("responseString = \(responseString)");
return
}
print("This is the task string")
task.resume()
You can't return from a closure, you need to use a "callback".
We make a function for your code:
func getData(username username: String, password: String)
but instead of adding a return type, we add a callback, here named "completion":
func getData(username username: String, password: String, completion: (response: String)->()) {
}
And inside the function, we use this callback at the location where the data will be available:
func getData(username username: String, password: String, completion: (response: String)->()) {
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8888/mobilelogin.php")!)
request.HTTPMethod = "POST"
var postString = "username="
postString += username
postString += "&password="
postString += password
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard let data = data where error == nil else {
fatalError(error!.debugDescription)
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
print("response = \(response)")
fatalError("statusCode should be 200, but is \(httpStatus.statusCode)")
}
guard let str = String(data: data, encoding: NSUTF8StringEncoding) else {
fatalError("impossible to get string from data")
}
completion(response: str)
}
task.resume()
}
And you will use it like this:
getData(username: email_input.text!, password: password_input.text!) { (response) in
print(response)
}