cocoa http post request - objective-c

hello i know this has been asked and answered many times but i cant seem to understand how it works (im new to iphone dev & objective c in general)
i am trying to make a create user for my app. i have a file create.php on my server that expects to get a _POST variable called id. after it is called it echos "DONE" for success and "EXIT" for failure.
i found some code and altered it (to the best of my knowledge) to fit my needs :
NSMutableString *tmpurl = [NSMutableString stringWithString: #"http://mysite.com/"];
[tmpurl appendString:#"create.php"];
NSURL *url = [NSURL URLWithString:tmpurl];
NSString *uid = #"32478907348920437829078902347804930893741"; // should chenge for randome.
NSString *post = [NSString stringWithFormat:#"id=%#", uid];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
now i don't know how to see what the page echos back or even if it has reached it.
any information would be appreciated and thank you in advance.

You are missing the NSURLConnection. Depending if you want to send this request synchronous or async, you may need to implement the NSURLConnectionDelegate methods.

Related

send post request with dynamic data

good afternoon
I have been looking but I haven't found anything similar
I am starting with Xcode and objective C please you be patient with me
I want do this
I have a text field intended to be a search box
currently I send a POST request programmatically and the parameters are static
well, I want dynamic parameters
the content of the text field is dynamic parameters
how do I can do it?
I have also a button for sending the request
help please
this is code of the request
NSString *Post = [[NSString alloc] initWithFormat:#"query=deporte"];
NSURL *Url = [NSURL URLWithString:#"http://www.laleo.com/ebooks_android/ebooks_search_json.php"];
NSData *PostData = [Post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [PostData length]];
NSMutableURLRequest *Request = [[NSMutableURLRequest alloc] init];
[Request setURL:Url];
[Request setHTTPMethod:#"POST"];
[Request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[Request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[Request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[Request setHTTPBody:PostData];
NSData *returnData = [NSURLConnection sendSynchronousRequest:Request returningResponse:nil error:nil];
//NSString *myString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError *error;
NSMutableDictionary *allCourses = [NSJSONSerialization
JSONObjectWithData:returnData
options:NSJSONReadingMutableContainers
error:&error];
The text field already is available through of #synthesize palabra;
The button is in the graphical interface
First of all, you should create an action handler for your button. Use Interface Builder for that. Also you'll need to connect the outlet for the textfield with your viewcontroller's class. Then, just take a text value from your textfield and send it into the request. If you need to know how you can receive a text from the textfield, just use this:
NSString *text = _textField.text;

Asynchronous POST to server

The goal is to do a simple username/password authentication by querying a database. Until the connection is working decently my php destination file simply has following code:
echo "Posted: " . $_POST['email'];
The code to do this synchronously is this:
NSString *post = [[NSString alloc] initWithFormat:#"email=%#&password=%#", self.email.text, ..]; // .. simplified keychainItem
NSData *postEncoded = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:#"%d", [postEncoded length]];
NSURL *url = [NSURL URLWithString:#"http://eng.studev.groept.be/web2.0/a11_web02/improver/app/testPost"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postEncoded];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *encodedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *data=[[NSString alloc]initWithData:encodedData encoding:NSUTF8StringEncoding];
NSLog(#"Data? %#",data);
The correct value is shown as an echo. But when trying to do this asynchronously, I get following php error: "Undefined index: email".
I try to start the asynchronous request with this line:
[[NSURLConnection connectionWithRequest:request delegate:self] start];
Then, I have the delegate method connection:didReceiveResponse, but there I cannot seem to get the data out... Or do I need another delegate method? Also, how 'safe' is it to check the result of your query by using just an echo (do I need/want a stream maybe?) ??
Tia
EDIT
Problem related to the server, not to objective-C code. Asked a new question to reach the correct audience: $_POST remaining empty
#ott is on the right track, I'll try to clarify.
You don't need start as he says. It's benign as the connection will start automatically.
initWithRequest:delegate and connectionWithRequest:delegate: are equivalent except for the retain state of the new connection object.
The real problem is b/c you are using connectionWithRequest:delegate the returned connection is autoreleased at the end of the run loop and you are not retaining it in a property. Therefore, the connection never starts.
The solution is to add a property #property (nonatomic, retain) NSURLConnection *connection to your class and set this property to the connection returned from connection:withRequest:
You then release the connection in the completion methods connection:didFinishLoading and connection:didFailWithError:.
The start is wrong here. Simply use
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
with NSURLConnection *connection; defined. See the class reference for connectionWithRequest. start is to be used with initWithRequest:delegate:.

sending data to a server from ipad

i m developing an ipad app for hospital management were information is filled in the user interface and on the click of a button the data is to be transfered to an external database(which later be viewed)...what are the steps required
You need to set up a webservice (like Saurabh said), for instance a PHP file using an mySQL connection would do fine.
To post the data (unsecured) to the service you can dome something like this:
NSString *post = #"key1=val1&key2=val2";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http://www.someurl.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content- Type"];
[request setHTTPBody:postData];
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
Read the NSURLConnection documentation
You need to create webservices on your server to add data in your database
see the answer of this question to know how to send data
Send data from an iPhone to a Web service

How to escape all special chars before encoding a string used in a simple http post -objective-c

I'm building a request that will be a simple http POST. Inside this post I need to add a few items and one of these is a large viewstate string that is pulled down during a previous request. What I've noticed is that the raw request needs to have all special chars escaped (like the below)
_EVENTTARGET=&_EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUENTM4MQ9kFgJmD2QWAmYPZBYCZg9kFgJmD2QWAgIBEGRkFgQCAQ9kFgICBw9kFgJmD2QWCmYPFgIeA3NyYwUpL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtcmVudG9ubGluZS5wbmdkAgEPFgIfAAUlL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtc3BhY2VyLnBuZ2QCAg8WAh8ABSUvYXNzZXRzL2ltYWdlcy9zaXRlbWFpbm5hdi1tb3ZpZXMucG5nZAIDDxYCHwAFJS9hc3NldHMvaW1hZ2VzL3NpdGVtYWlubmF2LXNwYWNlci5wbmdkAgQPZBYCZg9kFgZmDxYCHwAFLi9hc3NldHMvaW1hZ2VzL3NpdGVtYWlubmF2LWtpb3Nrc2Fub255bW91cy5wbmdkAgEPFgIfAAUlL2Fzc2V0cy9pbWFnZXMvc2l0ZW1haW5uYXYtc3BhY2VyLnBuZ2QCAg8WAh8ABSgvYXNzZXRzL2ltYWdlcy9zaXRlbWFpbm5hdi1idXlPbmxpbmUucG5nZAICD2QWAgIBD2QWAgIGD2QWAgIBD2QWAmYPZBYCAgIPEA8WAh4EVGV4dAVTUmVjb2duaXplIG1lIGZvciAxNCBkYXlzIChEbyBub3QgY2hlY2sgdGhpcyBib3ggaWYgeW91IGFyZSB1c2luZyBhIHNoYXJlZCBjb21wdXRlcilkZGRkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYBBVVjdGwwMCRjdGwwMCRjdGwwMCRjdGwwMCRNYWluQ29udGVudCRNYWluQ29udGVudCRNYWluQ29udGVudCRiYnhsb2dpbl83JGNoa1JlY29nbml6ZU1lNZH1xfrz8glwi2XmQJFTCJ0dMNk%3D&
But I'm not certain that I've done this in objective-c. Currently when I NSLog out the viewstate string it is still showing / and = characters.
Can anyone verify I'm on the right path here? And if not how would I convert the special chars in viewstate (ie - instead of = I should get %3D)?
- (void)doHttpPostWithViewState:(NSString *)viewstate
{
responseData = [[NSMutableData data] retain];
NSURL *url = [NSURL URLWithString:#"https://localhost/Login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSString* theBodyString = [[NSString alloc] initWithFormat:#"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%#",viewstate];
NSData *requestData = [theBodyString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: requestData];
[request setAllHTTPHeaderFields:headers];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
And finally, for local debugging purposes- how can I use NSLog to view the final (raw) string that will be sent to the client? Thank you in advance!
Update
Turns out this is a bug in the stringByAddingPercentEscapesUsingEncoding method
I've found the following to work from this blog post
NSString * cleanViewState = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)viewstate,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8 );
You're probably looking for the stringByAddingPercentEscapesUsingEncoding: method on NSString to %-encode your POST request.
Update:
If the NSString method isn't getting all the special characters you need, the next step is to drop down to the Core Foundation level function (CFURLCreateStringByAddingPercentEscapes), which gives you better control. See http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

Put JSON encoded array as NSData from NSURLResponse into NSArray

I'm unable to get this to work:
NSString *post = [NSString stringWithFormat:#"userudid=%#", [udid stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",post);
NSData *postData = [NSData dataWithBytes:[post UTF8String] length:[post length]];
//[udid dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSLog(#"%#",postData);
//NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.myserver.com/myapp/readtags2.php"]];
[request setURL:url];
[request setHTTPMethod:#"POST"];
//[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *error;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response error:&error];
NSString *content = [NSString stringWithUTF8String:[urlData bytes]];
NSLog(#"responseData: %#", content);
is the POST formed correctly? Because i can get it to work from a manual html form posting to the same php file, but i get nothing back when doing it from iOS
You might have an easier time doing HTTP POST's with ASIHTTPRequest.
Form-Posting with ASIHTTPRequest is explained in the section titled "Sending a form POST with ASIFormDataRequest" here: http://allseeing-i.com/ASIHTTPRequest/How-to-use
Otherwise, have a look at the NSURLResponse, check the response code and see if iOS thinks the POST was successful.
Other thing you can use to check is a tool like wireshark to compare the network traffic from your web-based form POST to the traffic from your iOS POST. It looks like you're doing it right, but the best way to be sure is something like wireshark.