Asynchronous POST to server - objective-c

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:.

Related

How do I POST JSON data object to server iOS8?

I want to send a new object created on iOS to a receiving server with a POST method using JSON data type. From what I know about receiving data from the server in iOS, is that all JSON handling was simplified by Apple with the introduction of iOS 8. But in contradistinction to GETting JSON objects, POSTing those isn't really described anywhere I could find ...
The first steps I took to try and solve the problem looked as follows:
How can I send the below format to server???
{"createFrom":"","createType":"","filename":"AC","filter":"","lstData":[{"FieldName":"LNK_RELATED_CN","FieldValue":""},{"FieldName":"LNK_RELATED_CO","FieldValue":""},{"FieldName":"MLS_PURPOSE","FieldValue":"Inquiry"},{"FieldName":"MLS_STATUS","FieldValue":"Open"},{"FieldName":"MMO_NOTES","FieldValue":""},{"FieldName":"DTE_NEXTACTIONDATE","FieldValue":""},{"FieldName":"MMO_NEXTACTION","FieldValue":""}],"password":"Infodat2","username":"manmeets","IsNew":true}
I have seen code like this:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:#"%#AssetSave",[defaults objectForKey:#"siteAddress"]]];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:jsonData];
_responseData = [NSMutableData data];
NSLog(#"request : %#", request);
_nsurlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
But I really don't know how to send a JSON object to a server using a POST method at all. Could anybody please help me out?
The code you have is fine, you just need to create jsonData:
jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
(thought you should really also include an &error so you can see what's happening if something goes wrong)

HTTP "GET" Method Not Returning Any Data in Objective-C

I've already ran a "POST" method to my API, and I successfully retrieved my token, username, and other data.
Now as I run my "GET" method in Xcode, it seems as though I'm not getting any data at all. I ran my Web API through fiddler, and data is being returned, so I know it must be a problem with my code.
Here is the code for my get request (I pass in my token to receive my profile data) :
NSString *get = [NSString stringWithFormat:#"g0pww0uXSrffNtJWWUrguHo-Zwr85EvtbKpAk46oea1Ayl2s7mncoDcXF8f-IJcBrWdxuGFYX3Ua5Tv7ea_IT0HWDB4nyVXrJKrU5f2gpnry4f-qF8zlyaMOQloVIIcqQo0nOY9B87cxvSlAwkZR4hub7CPvXMGpHAJixov2Sb-sE8jEv--cJ1l0Cfr6f3E0nX47-GdalB1XCtIJZgX6ZqpRWxqFaiMKRSZpD5-n087nSfUwQLNAIIA4AG8Hljh1yw3gCHi8fz40ARqkFyOIoXJm6tjtbwZGM44imm4DgP1GeDRqSkM7rVHUeMNmzsmsZWcAxMXDb_P9GbvLwD4_AqsTvuZ00r5UaydPB4m-po4jDf_e3HRKkUOQHAD3jTG_I2TUd6QD3mEyKbK41JsjDDv0LaLvBfTCUskZJKOjXDRanwQJWkselAv5cc5-bEIpvw7HYuFf1lM-O0LSLAXeGYfZS7H-KOdFPJCFUAGO0RH7zdJgatO-sqdx0GNyN_E3"];
NSData *getData = [get dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *getLength = [NSString stringWithFormat:#"%lu", (unsigned long)[getData length]];
NSMutableURLRequest *getRequest = [[NSMutableURLRequest alloc] init];
[getRequest setValue:#"Bearer g0pww0uXSrffNtJWWUrguHo-Zwr85EvtbKpAk46oea1Ayl2s7mncoDcXF8f-IJcBrWdxuGFYX3Ua5Tv7ea_IT0HWDB4nyVXrJKrU5f2gpnry4f-qF8zlyaMOQloVIIcqQo0nOY9B87cxvSlAwkZR4hub7CPvXMGpHAJixov2Sb-sE8jEv--cJ1l0Cfr6f3E0nX47-GdalB1XCtIJZgX6ZqpRWxqFaiMKRSZpD5-n087nSfUwQLNAIIA4AG8Hljh1yw3gCHi8fz40ARqkFyOIoXJm6tjtbwZGM44imm4DgP1GeDRqSkM7rVHUeMNmzsmsZWcAxMXDb_P9GbvLwD4_AqsTvuZ00r5UaydPB4m-po4jDf_e3HRKkUOQHAD3jTG_I2TUd6QD3mEyKbK41JsjDDv0LaLvBfTCUskZJKOjXDRanwQJWkselAv5cc5-bEIpvw7HYuFf1lM-O0LSLAXeGYfZS7H-KOdFPJCFUAGO0RH7zdJgatO-sqdx0GNyN_E3" forHTTPHeaderField:#"Authorization"];
[request setURL:[NSURL URLWithString:#"http://appointmentreminder4.azurewebsites.net/Profile"]];
[getRequest setHTTPMethod:#"GET"];
[getRequest setValue:getLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:getData];
NSURLResponse *getRequestResponse;
NSData *getRequestHandler = [NSURLConnection sendSynchronousRequest:getRequest returningResponse:&getRequestResponse error:nil];
NSString *getRequestReply = [[NSString alloc] initWithBytes:[getRequestHandler bytes] length:[getRequestHandler length] encoding:NSASCIIStringEncoding];
NSLog(#"getRequestReply: %#", getRequestReply);
The output is this:
2014-12-30 11:32:23.384 ARTest[612:303] getRequestReply:
Program ended with exit code: 0
All help is appreciated :)
EDIT:
getRequestHandler returns (null)
getData returns A BUNCH of populated data

Can't send data from objective-c via POST

i'm developing an app for iPhone and I'm stuck in one call, I have to send data via POST, the django web programmer tells me the app has to receive
param_one = request.POST['param_one']
param_two = request.POST['param_two']
but I cannot make it to send any data...
I'm learning objective-c, so please, could you tell me how to do it with an example?
PS: all the other calls that doesn't send any data, or pass data through url (GET method) works fine, so I'm making the connection correctly
Here's the code I'm using:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"somename" forKey:#"user"];
NSString *jsonString = [dict JSONRepresentation];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *  request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://web.com/custom/url/call/"]];
[request setValue:jsonString forHTTPHeaderField:#"json"];
[request setHTTPMethod:#"POST"];
[request addValue:csrf forHTTPHeaderField:#"X-CSRFToken"];
[request setHTTPBody:jsonData];
senddata = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You should probably add:
[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
Then the server will know that what you're sending is UTF-8 encoded JSON and it will be able to parse it appropriately. Otherwise it just gets a formless blob of data.
Unless it's for debugging purposes, it's very odd that you put the JSON string into both the header and the body.

cocoa http post request

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.

Properly handling NSURLConnection errors

I have a simple form interface set up that send username and password information to a server: (working)
NSString *postData = [NSString stringWithFormat:#"user=%#&pass=%#",[self urlEncodeValue:sysUsername],[self urlEncodeValue:password]];
NSLog(#"Post data -> %#", postData);
///
NSData* postVariables = [postData dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];
NSString* postLength = [NSString stringWithFormat:#"%d", [postVariables length]];
NSURL* postUrl = [NSURL URLWithString:#"http://localhost/~csmith/cocoa/test.php"];
[request setURL:postUrl];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: postVariables];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];
NSLog(#"Post data SENT & returned -> %#", returnData);
How do I handle connection errors such as no internet connection, firewall, etc.
Also, does this method use the system-wide proxy settings? Many of my users are behind a proxy.
Thanks a lot!
First, you shouldn't use synchronous requests, use asynchronous request instead and indicate activity using indeterminate progress indicators.
When using asynchronous requests, you have to set a delegate implement delegate methods, notably:
-connectionDidFinishLoading:
-connection:didFailWithError:
From the docs:
Unless a NSURLConnection receives a cancel message, the delegate will receive one and only one of connectionDidFinishLoading:, or connection:didFailWithError: message, but never both. In addition, once either of messages are sent, the delegate will receive no further messages for the given NSURLConnection.
As for the last question:
Also, does this method use the system-wide proxy settings?
Yes, NSURLConnection uses them automatically.
You should use asynchronous request to handle proxy and network errors. This is more efficient.
To add extra check you can add reach-ability test in your code before communications. you can find reach-ability test code here