harp
harp

Reputation: 129

How to send a variable from iOS to php file

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

Answers (3)

harp
harp

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

harp
harp

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

Rob
Rob

Reputation: 437622

A couple of points:

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

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

  3. 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).)

  4. 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
    
  5. 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

Related Questions