Reputation: 129
I have a simple task, send one variable to a php page via GET. Nothing I seem to find works, and all are seemingly more than I need.
It seems I need code to set NSURL string, NSURL request, then execute.
Can someone perhaps paste me some simple code to just execute a URL like this:
http://localhost/trendypieces/site/ios/processLatest.php?caption=yosa
Thanks!
Here's the most current iteration of something that doesn't work, seems closer though as it actually throws back the error alert. Dunno what that error is...but....
//construct an URL for your script, containing the encoded text for parameter value
NSURL* url = [NSURL URLWithString:
[NSString stringWithFormat:
@"http://localhost/trendypieces/site/ios/processLatest.php?caption=yosa"]];
NSData *dataURL = [NSData dataWithContentsOfURL:url];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
if([serverOutput isEqualToString:@"OK"]) {
alertsuccess = [[UIAlertView alloc] initWithTitle:@"Posted" message:@"Done"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
} else {
alertsuccess = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Done"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
}
[alertsuccess show];
Upvotes: 0
Views: 621
Reputation: 129
Here it is adapted for POST with two variables, thanks to @Rob for code from another post.
NSURL *url = [NSURL URLWithString:@"http://192.168.1.5/trendypieces/site/ios/processLatest.php"];
NSString *var2 = @"variable2";
NSString *postString = [NSString stringWithFormat:@"caption=%@&var2=%@", _captionField.text, var2];
NSData *postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:postBody];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//initialize a connection from request, any way you want to, e.g.
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Upvotes: 0
Reputation: 129
So the main problem was trying to hit localhost from the phone and not the simulator, duh. The code that runs successfully now is below. Thanks to all for the help.
NSURL *url = [NSURL URLWithString:@"http://localhost/trendypieces/site/ios/processLatest.php?caption=mycaption"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"GET"];
returnData = [[NSMutableData alloc] init];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
Upvotes: 0
Reputation: 437622
A couple of points:
When you create a NSURLConnection
with initWithRequest:delegate:
, it automatically starts the connection. Do not call the start
method yourself (in some cases, it can interfere with the initial connection). That is only intended for when you use initWithRequest:delegate:startImmediately:
with NO
for that final parameter.
You then say:
Current code that yields no active result (from within an IBAction function)
Your code would not yield any "active result" within the IBAction
method. It would call the NSURLConnectionDataDelegate
and NSURLConnectionDelegate
methods. Have you implemented them? Notably, make sure you also implement connection:didFailWithError:
, which will tell you if there were any connection errors.
If you need the result in the IBAction
method, you should use the NSURLConnection
method sendAsynchronousRequest
.
Going to the title of this question, "how to send a variable", you should be careful about just adding user input to a URL. (This isn't your immediate problem why you're not getting any reply, but this is important when sending the contents of a variable to a web server.)
Notably, the caption=xxx
portion, the xxx
cannot contain spaces or reserved characters like +
, &
, etc. What you have to do is percent-encode it. So, you should:
NSString *caption = ... // right now this is @"yosa", but presumably this will eventually be some variable
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
// [data release]; // if not ARC, insert this line
//initialize url that is going to be fetched.
NSString *encodedCaption = [self percentEscapeString:caption];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost/trendypieces/site/ios/processLatest.php?caption=%@", encodedCaption]];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = connection;
// [connection release]; // if not ARC, insert this line
// DO NOT start the connection AGAIN
//[connection start];
Where that percentEscapeString
is defined as:
- (NSString *)percentEscapeString:(NSString *)string
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)string,
(CFStringRef)@" ",
(CFStringRef)@":/?@!$&'()*+,;=",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}
(Note, there is a promising NSString
method, stringByAddingPercentEscapesUsingEncoding
, that does something very similar, but resist the temptation to use that. It handles some characters (e.g. the space character), but not some of the others (e.g. the +
or &
characters).)
Finally, you say that this is a GET
request (which, implies you're not changing anything on the server). If it really is a GET
request, see my prior point. But if this request is really updating data, you should be doing a POST
request (where the caption=yosa
goes in the body of the request, not the URL). This has another advantage as there are limitations as to how long a URL can be (and therefore what how long the parameters can be when you submit them in the URL in a GET
request).
Anyway, if you wanted to create a POST
request, it would be like:
NSString *caption = ... // right now this is @"yosa", but presumably this will eventually be some variable
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
// [data release]; // if not ARC, insert this line
//create body of the request
NSString *encodedCaption = [self percentEscapeString:caption];
NSString *postString = [NSString stringWithFormat:@"caption=%@", encodedCaption];
NSData *postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
//initialize url that is going to be fetched.
NSURL *url = [NSURL URLWithString:@"http://localhost/trendypieces/site/ios/processLatest.php"];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:postBody];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = connection;
// [connection release]; // if not ARC, insert this line
While your initial code sample was using a delegate-based NSURLConnection
, you've revised your answer to use dataWithContentsOfURL
. If you really don't want to use the delegate-based NSURLConnection
, then use its sendAsynchronousRequest
instead, which offers the simplicity of dataWithContentsOfURL
, but allows you to use either GET
or POST
requests, as well as performing it asynchronously. So, create the NSMutableURLRequest
as shown above (use the appropriate method code depending upon whether you're GET
or POST
), eliminate the lines that instantiate the NSMutableData
and the NSURLConnection
and replace that with:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!data) {
NSLog(@"Error = %@", connectionError);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Error" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
return;
}
NSString *serverOutput = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"Data = %@", serverOutput);
UIAlertView *alert;
if ([serverOutput isEqualToString:@"OK"]) {
alert = [[UIAlertView alloc] initWithTitle:nil message:@"Posted" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
} else {
alert = [[UIAlertView alloc] initWithTitle:nil message:@"Not OK" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
}
[alert show];
}];
Upvotes: 2