3

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

?>
Samitha Nanayakkara
  • 2,529
  • 2
  • 10
  • 23
  • Not this issue? https://stackoverflow.com/questions/37825284/the-data-couldn-t-be-read-because-it-isn-t-in-the-correct-format – ficuscr Sep 13 '17 at 17:02
  • @ficuscr Tried them. Had no luck – Samitha Nanayakkara Sep 13 '17 at 17:05
  • what there is in some other code? are datas stored in database? are you give back json? are you sure you not printing some string somewhere? – Gabriele Carbonai Sep 13 '17 at 17:06
  • @GabrieleCarbonai I used some print function to check values in the swift code. Data are stored in SQLite database and retrieve them by FMDB library and convert to Strings. – Samitha Nanayakkara Sep 13 '17 at 17:09
  • try to open the file that create json by browser, if will be not correct format will be write in the browser and then you can working on it – Gabriele Carbonai Sep 13 '17 at 17:19
  • @GabrieleCarbonai I have mentioned what errors it says in my console. When I check PHP files and run them with text data, they work perfectly. – Samitha Nanayakkara Sep 13 '17 at 17:26
  • Put a breakpoint at the line `if error != nil` and then step through, so you can see exactly where the error occurs. When stepping through, check the values of data, response and error. My first guess is that your code is *not even reaching* your server, rather than the server actually returning an error message. – DonMag Sep 13 '17 at 20:17
  • @Sam94 - what do you get if you `print(response)`? – DonMag Sep 13 '17 at 20:23
  • This is what I get. `Optional( { URL: http://192.168.1.99/insertDataTest.php } { status code: 500, headers { Connection = close; "Content-Length" = 0; "Content-Type" = "text/html; charset=UTF-8"; Date = "Wed, 13 Sep 2017 20:26:05 GMT"; Server = "Apache/2.4.10 (Raspbian)"; } })` – Samitha Nanayakkara Sep 13 '17 at 20:26
  • OK - HTTP status code 500 is "Internal Server Error" ... Try it with a simpler PHP script that just returns the key/value elements that you're posting. You will still get the JSON error, but printing the `response` will let you see if you're actually passing the data ***to the server*** correctly. – DonMag Sep 13 '17 at 20:30
  • `insertDataTest.php` which I'm using now, only does is capture incoming POST data and set it to a variable and echo it using son_encode. That's all. – Samitha Nanayakkara Sep 13 '17 at 20:32
  • OK - just echo back the captured data... don't try to encode it. – DonMag Sep 13 '17 at 20:35
  • @DonMag This is what I get `Optional( { URL: http://192.168.1.99/insertDataTest.php } { status code: 200, headers { Connection = "Keep-Alive"; "Content-Length" = 0; "Content-Type" = "text/html; charset=UTF-8"; Date = "Wed, 13 Sep 2017 20:38:53 GMT"; "Keep-Alive" = "timeout=5, max=100"; Server = "Apache/2.4.10 (Raspbian)"; } })` – Samitha Nanayakkara Sep 13 '17 at 20:39
  • @Sam94 - trying to figure out if the data being *sent* is correct. Looks like `$userPhone` is empty. – DonMag Sep 13 '17 at 20:48
  • @DonMag I did send this string `"\"usermobilenum\":12345"` But still shows in the response that `"Content-Length" = 0;`. I spent days on this. Cannot find a single mistake. – Samitha Nanayakkara Sep 13 '17 at 20:53
  • Maybe try ` $requestBody = file_get_contents('php://input'); echo "Body: [".$requestBody."]"; >` ? (My php is rusty, so fix that if it's not quite right) – DonMag Sep 13 '17 at 20:53
  • @Sam94 - by the way... are you trying to use `.data(using: String.Encoding.utf8)` for a specific reason? I expect that is sending something other than what php is expecting as the post data... – DonMag Sep 13 '17 at 21:01
  • @DonMag A good news. I just did as you asked. Then I print the response and got this. `Optional( { URL: http://192.168.1.99/insertDataTest.php } { status code: 200, headers { Connection = "Keep-Alive"; "Content-Length" = 5; "Content-Type" = "text/html; charset=UTF-8"; Date = "Wed, 13 Sep 2017 20:59:52 GMT"; "Keep-Alive" = "timeout=5, max=100"; Server = "Apache/2.4.10 (Raspbian)"; } })` – Samitha Nanayakkara Sep 13 '17 at 21:01
  • @DonMag I sent ` "{\"usermobilenum\":12345}"`. So received same content length :D – Samitha Nanayakkara Sep 13 '17 at 21:02
  • What if you simply do: `request.httpBody = postParameters` instead of the utf8 data encoding? – DonMag Sep 13 '17 at 21:02
  • @DonMag ACTUALLY I use that encoding because some people suggested to do so because of this problem. Also since that is a string file and won't let me to add that to request.httpBody. – Samitha Nanayakkara Sep 13 '17 at 21:03
  • @Sam94 - I've gotta run, but... I strongly suspect the problem is in how you're formatting the *send* part (although, in your original php script, you are echoing back "Success" which, of course, would fail to parse as JSON, but anyway...). Take a look at this post - it looks like a pretty well examined method: https://stackoverflow.com/a/31938246/6257435 – DonMag Sep 13 '17 at 21:11
  • @DonMag Thank you very much for your help. Have a nice day – Samitha Nanayakkara Sep 13 '17 at 21:14

2 Answers2

0

{"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()
}
Amir Khan
  • 1,318
  • 1
  • 14
  • 39
  • I don't know man. Still get these two errors. `The data couldn’t be read because it isn’t in the correct format.` `Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}` – Samitha Nanayakkara Sep 13 '17 at 19:14
  • @Sam94 echo your requested value at server end. try to echo $userPhone and $contatcNum and check what it gets from the app. – Amir Khan Sep 13 '17 at 19:17
  • I updated full PHP code in my question. I do run remote server in Raspberry Pi. There I cannot find any output like this. But I can assure that code works pretty well since that PHP code has been checked by several test data. – Samitha Nanayakkara Sep 13 '17 at 19:19
  • @Sam94 as per as your php code, you didn't send any response to the API call. Try to make an encoded response and send back to the App. Because it waits for the server response whether its a success or failure. – Amir Khan Sep 13 '17 at 19:23
  • I did once. I did use json_encode and echo every message when it fails. If it passes, it obviously has to update the data base right? Anyhow when I did that, still it didn't showed anything on my console. Only these two errors. – Samitha Nanayakkara Sep 13 '17 at 19:29
  • Have you echo these variable value - $userPhone and $contatcNum? What these are getting. – Amir Khan Sep 13 '17 at 19:30
  • Echo them. Shows nothing. – Samitha Nanayakkara Sep 13 '17 at 19:42
0

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.

Akii_iOS
  • 53
  • 1
  • 10
  • its means your not getting any response from server. ask your server guy to make change in "echo json_encode" something. that surely help. :) – Akii_iOS Sep 13 '17 at 19:29
  • I have added my PHP code as well. My remote database is my raspberry pi and I'm working on a project. When even I encode and echo something, it still doesn't show in my console. – Samitha Nanayakkara Sep 13 '17 at 19:30
  • see before die(mysqli_error($connect)); there is nothing ask to add some code there for output. line 27 and line 53 something. – Akii_iOS Sep 13 '17 at 19:31
  • I did echo son_encode(mysqli_error($connect)) in every place where I expect to kill the connection with error. But it still shows nothing. – Samitha Nanayakkara Sep 13 '17 at 19:34
  • can you share URL So I can check it or hit that url on browser and check output please – Akii_iOS Sep 13 '17 at 19:39
  • It's on my local network. Basically what you have to do is run that PHP script in your local server and that swift code right? – Samitha Nanayakkara Sep 13 '17 at 19:43
  • Yes something like. I dont have that much idea about PHP I only can do basic code which help me in swift... :D – Akii_iOS Sep 13 '17 at 19:46
  • Ah sorry. I deleted all code of my PHP and just echo POST value. But nothing shows on my console. As I saw, in swift, this error was being captured by try catch. – Samitha Nanayakkara Sep 13 '17 at 19:49
  • Good. So you done with problem finally. Good luck. Enjoy. (y) – Akii_iOS Sep 13 '17 at 19:54
  • Actually I didn't solve the problem. It still persist. I need help – Samitha Nanayakkara Sep 13 '17 at 19:55
  • what is your problem now? how can help you? – Akii_iOS Sep 13 '17 at 19:57
  • in the catch statement it shows the error. I don't know how that happens. Data won't be uploaded to my database or don't echo anything from PHP. it catches in try and catch function. Which means I'm having the unknown problem in json serialization line. – Samitha Nanayakkara Sep 13 '17 at 20:02
  • See swift throwing error means there is something wrong in json serialisation. Check response json on console. – Akii_iOS Sep 13 '17 at 20:06
  • I have no idea why anyone don't understand. I have only one error in the console. That is `The data couldn’t be read because it isn’t in the correct format.` which obtain by `error.localizedDescription` . Other than that I have no idea what this heck. – Samitha Nanayakkara Sep 13 '17 at 20:08
  • Sorry man I cant help you without checking your php server response. for now I am done. – Akii_iOS Sep 13 '17 at 20:11