I'm working on a project where I need to send some data to the remote database. So I'm developing an iOS app using Swift 3.1 and when I try to send data to the database it says,
The data couldn’t be read because it isn’t in the correct format.
Also there is another error;
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
This is my swift code:
let urlOfSMARTCF = URL(string: "http://192.168.1.99/insertData.php")
let request = NSMutableURLRequest(url: urlOfSMARTCF! as URL)
request.httpMethod="POST"
request.addValue("application/json", forHTTPHeaderField: "Accept")
for contact in contactsCaptuure
{
let userMobileNumber = DBManager.shared.retriveRegisteredNumberOfMobile()
let postParameters = "{\"usermobilenum\":\(String(describing: userMobileNumber!)),\"contactnum\":\(contact.phoneNumber!)}";
request.httpBody = postParameters.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error is \(String(describing: error))")
return;
}
do
{
let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = myJSON
{
var msg : String!
msg = parseJSON["message"] as! String?
print(msg)
}
}
catch
{
print(error.localizedDescription)
print(error)
}
}
print("Done")
task.resume()
}
This is my PHP in remote database:
<?php
if($_SERVER["REQUEST_METHOD"]=="POST")
{
require 'connectDB.php';
$userPhone = $_POST["usermobilenum"];
$contactNum = $_POST["contactnum"];
$query = "SELECT * FROM user WHERE UserMobNum='".$userPhone."'"; // Usermobile is registered.SIP exists.
if($results= mysqli_query($connect,$query))
{
if(mysqli_num_rows($results)>0)
{
$i=0;
while($rows=mysqli_fetch_assoc($results))
{
$sip[$i] = $rows["SIP"];
$i++;
}
$queryToAddData = "INSERT INTO user (UserMobNum,SIP,Phone) VALUES ('".$userPhone."','".$sip[0]."','".$contactNum."')";
if(mysqli_query($connect,$queryToAddData))
{
//Return success message to the app
echo "Success"
}
else
{
die(mysqli_error($connect));
}
}
else
{
$availableSIP=false;
while($availableSIP==false) // Assign a random value until it's being a valid one.
{
$sip[0]=rand(1,9999);
$queryToCheck = "SELECT * FROM user WHERE SIP='".$sip[0]."'";
if($results= mysqli_query($connect,$queryToCheck))
{
if(mysqli_num_rows($results)==0)
{
$availableSIP=true;
}
}
}
$queryToAddData = "INSERT INTO user (UserMobNum,SIP,Phone) VALUES ('".$userPhone."','".$sip[0]."','".$contactNum."')";
if(mysqli_query($connect,$queryToAddData))
{
//Return success message to the app
echo "Success"
}
else
{
die(mysqli_error($connect));
}
}
}
else
{
echo "First Level Failure!";
die(mysqli_error($connect));
}
mysqli_close($connect);
}
else
{
echo "Failed in POST Method"
}
?>
What I did
Went through all of stack overflow and other site suggestions but had no luck. I even checked my jSon string using a json validator and it passed. This is how my jSon string looks like.
{"usermobilenum":1234567890,"contactnum":9345}
However after some search I found that this happens because Remote database PHP sends this error message. So I checked each and every variable in PHP but couldn't find any problem. Also this couldn't be a problem with PHP cause I work with those exact php files when I connect to via my android app. That works fine. But in iOS it generates that error. Can someone help me please?
UPDATE
This is insertdataTest.php file:
<?php
if($_SERVER["REQUEST_METHOD"]=="POST")
{
$userPhone = $_POST["usermobilenum"];
echo $userPhone;
mysqli_close($connect);
}
else
{
echo json_encode("Failed in POST Method");
}
?>
{"usermobilenum":1234567890,"contactnum": 9345} - this is treated as a String. It's not a VALID JSON.
Updated code:
let urlOfSMARTCF = URL(string: "http://192.168.1.99/insertData.php")
let request = NSMutableURLRequest(url: urlOfSMARTCF! as URL)
request.httpMethod="POST"
request.addValue("application/json", forHTTPHeaderField: "Accept")
for contact in contactsCaptuure {
let userMobileNumber = DBManager.shared.retriveRegisteredNumberOfMobile()
let postParameters = NSMutableDictionary()
postParameters["usermobilenum"] = userMobileNumber
postParameters["contactnum"] = contact.phoneNumber!
let jsonData = try? JSONSerialization.data(withJSONObject: postParameters, options: .prettyPrinted)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error is \(String(describing: error))")
return;
}
do {
let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any]
if let parseJSON: NSMutableDictionary = NSMutableDictionary(dictionary: myJSON as! NSMutableDictionary){
let msg = parseJSON["message"] as! String
print(msg)
}
}
catch {
print(error.localizedDescription)
print(error)
}
}
print("Done")
task.resume()
}
Buddy I debug you code and found that there is error in server response not in you code. try this and reply me ASAP please
before this line "let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary"
add "let str = String.init(data: data!, encoding: .utf8)
print(str ?? "error")"
I am waiting please.
Related
I'm currently working on an Xcode app that allows a user to register by sending data to my MySQL database. I just have a couple of questions.
The first question I have is on lines 10, 13, 15. I have a warning sent to me saying: "String interpolation produces a debug description for an optional value; did you mean to make this explicit?" Is there anyway I can change my code so that the value isn't optional?
Also, the response string that is sent is worded like: "responseString = Optional( This username is available)". I was planning on using the response string to display information to the user. Is there anyway that I can get rid of the parenthesis and well as the word optional?
#IBAction func TextFieldEditingDidChange(_ sender: Any) {
let request = NSMutableURLRequest(url: NSURL(string: "usernamecheck.php")! as URL)
request.httpMethod = "POST"
print("Request: \(request)")
let postString = "username=\(usernameTxt.text!)"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
} // Ends errror If statements
print("response = \(response)")
let responseString = NSString(data: data!, encoding:
String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
}
portion PHP file:
$a_sql = mysqli_query($con, "SELECT username FROM users WHERE username = '" . mysqli_real_escape_string($_POST['username']) . "' ; ");
if (empty($_POST['username'])) {
$username_error = "Please input username";
} else {
$a_sql;
}
if ($a_sql && mysqli_num_rows($a_sql) > 0) {
$username_exists = "Username is already taken.";
echo $username_exists;
} else {
echo "Fail";
}
guard let unwrappedMessage = originalMessage else { return }
This is one of the ways to unwrap optionals but in the end it depends of what you want to do...
You should really read about optionals in Swift. It's very very easy and a beginner's topic that everyone learning Swift should learn
guard let message = responseString else {
return
}
print(message)
Actually, you are unwrapping an optional responsestring to message, now if it contains nil, it will not give any exception and it will fall into the else case.
On the other hand, the value will be stored in the message and can be used further
if let Message = Message {
print(Message)
}
It's almost a day since I'm working on my Login page of my App and I want to show to my app the errors (or whatever from the echo of PHP) to my xCode app. I'll show you my PHP file and my xCode
<?php
if($_SERVER['REQUEST_METHOD']=='POST')
{
$password = $_POST['password'];
$email = $_POST['email'];
if($password == '' || $email == '')
{
echo 'Please fill all values.';
}
else
{
require_once('GBconnect.php');
$sql = "SELECT * FROM Users WHERE email='$email' AND password='$password' OR mobile_no='$email' AND password='$password'";
$check = mysqli_fetch_array(mysqli_query($connection,$sql));
if(isset($check))
{
echo 'Login Success';
}
else
{
echo 'Email/Phone or Password is wrong.';
}
mysqli_close($connection);
}
}
else
{
echo 'error';
}
Here's my Swift file:
#IBAction func signUp(_ sender: Any)
{
let request = NSMutableURLRequest(url: NSURL(string: "http://34.205.37.201/restapi/GBlogin3.php")! as URL)
request.httpMethod = "POST"
let logEmail = "email=\(username.text!)&& password=\(password.text!)"
let logMobile = "mobile_no=\(username.text!)&& password=\(password.text!)"
if (username.text?.isEmpty)! || (password.text?.isEmpty)!
{
//display message
LoginInfoMyAlertMessage(userMessage: "Please input your Email or Phone and Password.");
}
if let checkNum = Int(username.text!)
{
print(checkNum)
request.httpBody = logMobile.data(using: String.Encoding.utf8)
}
let task = URLSession.shared.dataTask(with: request as URLRequest)
{
data, response, error in
if error != nil
{
print("error=\(String(describing: error))")
}
print("response = \(String(describing: response))")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(String(describing: responseString))")
}
task.resume()
username.text = ""
password.text = ""
return
A couple of things I see:
You specify logEmail but never use it anywhere
You have a space in logMobile but you should not when using application/x-www-form-urlencoded POST data
In a related item, you should use a more robust form encoding than concatenating strings.
You should use HTTP status codes to indicate success or failure, not strings. Use HTTP 200 for success, HTTP 401 for needing credentials, and HTTP 403 for invalid credentials
With all of that said, you haven't specified what you are seeing when you run the code. If you can do that, we can offer more specific advice. Use POSTMAN to verify that your server side works correctly, then you can ensure your client is working with the server.
You can encoding the response then unwrap in source app to handle the different messages.
<?php
$password = $_POST['password'];
$email = $_POST['email'];
if($password != '' || $email != ''){
$check = false; //Your connection
if($check){
echo json_encode([
"Message" => "Login Success",
"Status" => "Ok"
]);
}
else{
echo json_encode([
"Message" => "Email/Phone or Password is wrong.",
"Status" => "Error"
]);
}
}
?>
And then
#IBAction func signup(_ sender: Any) {
let request = NSMutableURLRequest(url: NSURL(string: "http://localhost:8888/chava/login.php")! as URL)
request.httpMethod = "POST"
let logEmail = "email=\(emial.text!) && password=\(password.text!)"
print(logEmail)
if (emial.text?.isEmpty)! || (password.text?.isEmpty)!{
print("Please input your Email or Phone and Password.");
}
request.httpBody = logEmail.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil{
print("error=\(String(describing: error))")
}else{
//print(String(data:data!,encoding: .utf8) ?? "")
if let resp = data {
do{
let jsonResult = try JSONSerialization.jsonObject(with: resp) as! [String:AnyObject]
if let message = jsonResult["Message"]{
print(message)
}
}catch{
}
}
}
//print("response = \(String(describing: response))")
//let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//print("responseString = \(String(describing: responseString))")
}
I hope help you !
I am trying to make registration in swift3 with mysql
but there is some thing wrong ,
when I run my app and make register return msg "some fields are empty"
In php code:
$fullname = htmlentities($_REQUEST["fullname"]);
$username = htmlentities($_REQUEST["username"]);
$email = htmlentities($_REQUEST["email"]);
$password = htmlentities($_REQUEST["password"]);
$phone = htmlentities($_REQUEST["phone"])
swift code:
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: "http://localhost/php/register.php?")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
let body = "fullname=\(FirstName.text)%20\(LastName.text)&username=\(UserName.text)&email=\(Email.text)&password=\(Password.text)&phone=\(Phone.text)"
request.httpBody = body.data(using: String.Encoding.utf8)
let task = session.dataTask(with: url!) {data, response, error in
if error != nil {
print(error!.localizedDescription)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
print(json)
}
} catch {
print("error in JSONSerialization")
}
}
}
task.resume()
I think you missed this
let task = session.dataTask(with: request) {data, response, error in
replace url with request
I have a Swift function for a button that when pressed writes some details into a database via PHP:
#IBAction func createCommunityButtonTapped(_ sender: AnyObject) {
let communityName = communityNameTextField.text;
if (communityName!.isEmpty){
displayMyAlertMessage(userMessage: "You must name your Community");
return;
}else{
func generateRandomStringWithLength(length: Int) -> String {
var randomString = ""
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for _ in 1...length {
let randomIndex = Int(arc4random_uniform(UInt32(letters.characters.count)))
let a = letters.index(letters.startIndex, offsetBy: randomIndex)
randomString += String(letters[a])
}
return randomString
}
let communityCode = generateRandomStringWithLength(length: 6)
passwordTextField.text = communityCode
let myUrl = URL(string: "http://www.quasisquest.uk/KeepScore/createCommunity.php?");
var request = URLRequest(url:myUrl!);
request.httpMethod = "POST";
let postString = "communityname=\(communityName!)&code=\(communityCode)&email=\(myEmail!)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if (try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]) != nil {
}
}
task.resume()
}
}
The function works great apart from whenever I add this echo jsonline into the PHP script:
if($newresult)
{
$returnValue["status"] = "Success";
$returnValue["message"] = "Community is registered";
echo json_encode($returnValue);
return;
}
Then I get an error Thread 8: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subside = 0x0) on this line:
if (try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]) != nil {
}
And in the debug area the following details
data Data? some
response URLResponse? 0x0000618000223500
error Error? nil none
I think I'm missing a line, or need to set a variable to the JSONSerialization instead of 'try!' but I'm very unsure what.
You are returning null. Try this
if($newresult)
{
$returnValue["status"] = "Success";
$returnValue["message"] = "Community is registered";
return json_encode($returnValue);
}
I am trying to try and learn swift but want a backend server for php and need to convert the php to json to the app
Now what I want is to put email and password in the fields on app and it send a post request to the php server side and the php validates the details and sends back the response which will let me then decide what to do with the response.
I have managed to post to the server side with success I think but when I get the response back in the xcode it gives the same output weather the details are correct or in-correct,I have looked every where and followed tutorials but I keep getting the same problem I'm guessing its the way I am check details in the php file as I always get the error and not success.
Could someone help?
login.php
$email = addslashes(strip_tags($_POST['email']));
$password = addslashes(strip_tags($_POST['password']));
$password = md5($password);
$returnValue = array();
$sql = "SELECT email, user_password FROM `Accounts` WHERE `email` = '$email' AND user_password = '$password' LIMIT 1";
$fetchuser = mysqli_query($db_connect, $sql);
$row = mysqli_num_rows($fetchuser);
if($row = mysqli_num_rows($fetchuser) == 0){
$returnValue["status"] = "error";
$returnValue["message"] = "Account not found";
echo json_encode($returnValue);
} else {
$returnValue["status"] = "success";
$returnValue["message"] = "Account found";
echo json_encode($returnValue);
}
Swift Code
let userEmail = UserEmailTextField.text;
let userPassword = UserPasswordTextField.text;
if(userEmail!.isEmpty || userPassword!.isEmpty) { return; }
//SEND TO SERVER
let request = NSMutableURLRequest(URL: NSURL(string: "http://chaozsounds.com/chaozsounds/New-ChaozSounds/TeamChaozApp/register.php")!)
request.HTTPMethod = "POST"
let postString = "email=\(userEmail)&password=\(userPassword)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
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!)")
}
let returnValue = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("returnValue = \(returnValue!)")
if(returnValue == "success") {
// LOGIN SUCCESSFUL
NSUserDefaults.standardUserDefaults().setBool(true, forKey:"isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion: nil);
}
}
task.resume()
Ok so had to work around and I managed to do what I was after so will put code below
// Send post request
let request = NSMutableURLRequest(URL: NSURL(string: "urllinkhere")!);
request.HTTPMethod = "POST";
let postString = "email=\(userEmail!)&password=\(userPassword!)";
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
// Get success or error
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if error != nil {
print("no data found: \(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!)")
}
// this, on the other hand, can quite easily fail if there's a server error, so you definitely
// want to wrap this in `do`-`try`-`catch`:
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json {
let returnValue = parseJSON["status"] as? String;
print("returnValue = \(returnValue!)")
if(returnValue == "success") {
// SUCCESS
NSUserDefaults.standardUserDefaults().setBool(true,forKey:"isUserLoggedIn");
NSUserDefaults.standardUserDefaults().synchronize();
self.dismissViewControllerAnimated(true, completion: nil);
}
}
} catch {
print(error)
}
}
task.resume()