0

I have an iPhone application where I'd like to send some form data to my site (which is written in PHP).

                     //This problem has now been solved. Typo in url.. :(
NSString *urlString = "http://www.mywebsite.com/test.php";
NSUrl *url = [NSURLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *variableToSend = [NSString stringWithFormat:@"name=John"];
//I have assumed that where I write "name=John" that "name" is in Php equal
//to $_POST['name']?, and that "John" is the value of it?

[request setHTTPMethod:@"POST"];

//I don't quite understand these..
[request setValue:[NSString stringWithFormat:@"%d", [variableToSend length]] forHTTPHeaderField:@"Content-length"];
[request setHTTPBody:[variableToSend dataUsingEncoding:NSUTF8StringEncoding]];

(void)[[NSURLConnection alloc] initWithRequest:request delegate:self];

My php-file just does $name = $_POST['name']; and writes $name to a database. I created a < form > with method="post", action="", with a textField with the name "name", and that worked. That value was sent to the database.

I have seen this code-example in many answers around, but it doen's work for me.. Some of the code-lines I don't understand, so I believe there is something wrong with how I set up the php vs how the code is sending the variable.. Anyone knows where I went wrong?

(The code is written by hand here now, so there might be typos, but everything compiles in xcode, and if I NSLog(@"%@", request), I get "< NSURLConnection: 0x1d342c24>" or something.. Don't know if this is correct..)

EDIT

My test.php

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title></title>
</head>
<body>


<?php

$connection = mysql_connect("host","un","pw");
if (!$connection){
 die('Error: ' . mysql_error());
}
if(isset($_POST['name']))
{

$name = $_POST['name'];
mysql_select_db("db", $connection);

mysql_query("INSERT INTO tablename(Name)
VALUES ('$name')");

mysql_close($connection);
}
?>
</body>
</html>

Sti

Sti
  • 8,275
  • 9
  • 62
  • 124
  • Did you google this? I am sure it must be all over the internet, in particular in In App Purchase sample code (don't have mine at hand right now) – Nicolas Miari Jul 18 '12 at 20:50
  • @ranReloaded Yes, I did, and I have tried several combinations of the code samples I have come over. The one I posted above is the most common answer around.. – Sti Jul 18 '12 at 21:02
  • Can you post your php code? I'll check my objective-C when I'm back to work and see if it's different from yours. – Nicolas Miari Jul 18 '12 at 21:08
  • Also, if you can avoid inserting client provided vars into your database, it would be safer. In my case, all the possible values are predetermined, so I pull the whole list from the DB and compare against the input until I find a match (whitelisting). Of course, doesn't work for arbitrary input, but there are many ways to 'sanitize'. – Nicolas Miari Jul 18 '12 at 21:11
  • @ranReloaded Many unfamiliar words there, but if I understood it fairly correct, I believe I can't do that. This is for Push-notification in my App, and I am storing the variable "token" in my database. Will update with php aswell. – Sti Jul 18 '12 at 21:14
  • OK, never done PNS before, only IAP. At least validate the passed variables in your server before inserting them into an SQL query (if that's what you're using). If you at least know the range of valid characters in your token (e.g., only numbers and letters), you can easily filter that with regular expressions. In addition, there are several php functions to escape special characters, each with its strengths and drawbacks, which I can't remember now/never actually mastered. But the internet is full of wisdom! – Nicolas Miari Jul 18 '12 at 21:59
  • So, the same php script you posted works OK when receiving POST data from an HTML form, but not from the iOS app? Can you print/log the body (html, error messages, etc.) of the RESPONSE you get from sending said request? (This entails NSLog'ing a string created from the 'data' property of the NSURLConnection, when it completes) – Nicolas Miari Jul 18 '12 at 22:05
  • OR alternatively, the HTTP error code (404, 500) if the NSURLConnection fails? – Nicolas Miari Jul 18 '12 at 22:06
  • Yes, it works from the form, and not from the app. I have already posted the NSLog the property from the connection. Instead of (void)[[NSURLConnection alloc] initWithRequest delegate:self]; I wrote NSLog(@"%@", [[NSURLConnection alloc] initWithRequest:request delegate:self]); and the log printed out "< NSURLConnection 0x12345678>", just with some other numbers.. – Sti Jul 18 '12 at 22:21
  • No, don't log the NSURLConnection object itself (that's just a memory address of the object), but an NSString initialized from connection.data, using NSUTF8StringEncoding. That should print whatever html/text/error messages that are returned by the script – Nicolas Miari Jul 18 '12 at 22:32
  • Ah, okay. Do you know the code for this? I have NSURLConnectio *test = [[nsurlconn alloc etc.]; NSLog(@"%@", test.? or [test ?]);..? – Sti Jul 18 '12 at 22:39
  • You need to implement the NSURLConnectionDelegate method for connectionDidFinish (don't remember the actual name) and get the data there. Also, I think you must 'start' the connection; allocating alone will not kick it off, unless you use initWithRequest:delegate:startImmediately:YES – Nicolas Miari Jul 18 '12 at 22:40

1 Answers1

1

I've realized your problem: your NSURLConnection instance is never starting (I bet none of your NSURLConnectionDelegate methods gets ever called).

Either use:

NSURLConnection* connection =     [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];

Or just:

[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

instead of the code you are using now.

Source:

http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

EDIT Don't forget to release the NSURLConnection object on failure AND success (exactly one of those gets called exactly once), or it will leak. If you are using ARC, keep it in an ivar or it could be deallocated right after starting (need confirmation on this one)

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
  • It sounded right, but it didn't work.. Maybe StartImmediately is set to YES by default when casting to void, anyway, I could not tell any difference.. I'll continue to try finding out how to get the error's etc. – Sti Jul 18 '12 at 22:58
  • Does any of your delegate methods get called? If the connection is successful, did you log the response data? – Nicolas Miari Jul 18 '12 at 22:59
  • I don't see how 'casting to void' would trigger the connection. And I believe the default is Not to start immediately. – Nicolas Miari Jul 18 '12 at 23:06
  • Which delegate methods are you reffering to? If I try if(connection){NSLog(@"Correct");} else{NSLog(@"Wrong");} , I get "Correct" printed out. Does this mean that the connection has been made, or that the NSURLConnection just isn't a null?.. – Sti Jul 18 '12 at 23:07
  • 1
    You set the connection's delegate to 'self'. Next, implement the essential methods of the protocol NSURLConnectionDelegate (hint: search Apple Dev Site) and your object will be notified of connection progress, success, failure, etc. That is, those methods will be called along the way and the connection object passed as an argument. On success, you can inspect connection.data as I said before. – Nicolas Miari Jul 18 '12 at 23:15
  • 1
    You must understand that successfully creating an instance of NSURLConnection, and have that object successfully establish an http connection to your server are two different things. Read the docs on how to use NSURLConnection, and if possible google for some sample code. – Nicolas Miari Jul 18 '12 at 23:17
  • 1
    My answer stands; the good news is that at least your php code is certainly working. But if you don't start the connection, it will not happen, And if you don't implement the delegate methods, you will never know what went wrong. – Nicolas Miari Jul 18 '12 at 23:18
  • Oh my god, I am so completely embarrassed right now..I knew I would come out of this looking like a retard.. I added the connectionDidFinishLoading, with a NSLog in it, nothing appeared.. I then found the didFailWithError-method, and logged out the NSError. "Error: A server with the specified hostname could not be found". I had a god damn typo in the website's url! One letter wrong, no wonder nothing worked. Now I have fixed it, and connectionDidFinishLoading logs great now, and my database even got updated. Wow.. Well, thank you so much for your wisdom and help! – Sti Jul 18 '12 at 23:30
  • 1
    Hey, it happens to all of us, all the time :) – Nicolas Miari Jul 18 '12 at 23:54