Shruti Kapoor
Shruti Kapoor

Reputation: 1126

Send array to PHP from objective C using POST/GET

I am trying to send an array of strings from Objective C to PHP. I was using GET initially but I got to know that GET is not suitable for sending large amount of data. My array would have approximately 300 entries. Therefore, I am using POST. After going through this page I came up with the following code

 NSDictionary *userconnections = [user objectForKey:@"connections"];
             NSMutableArray *connectionsID = [[NSMutableArray alloc] init];
             for (id foo in [userconnections objectForKey:@"values"]) {

                 [connectionsID addObject:[foo objectForKey:@"id"]];
                 //[User sharedUser].connections = connectionsID;

             }

             NSError *error;
             NSData *jsonData = [NSJSONSerialization dataWithJSONObject:connectionsID options:NSJSONWritingPrettyPrinted error:&error];

             NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
             [User sharedUser].connections = jsonData;
             [User sharedUser].connectionsID = jsonString;

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://localhost:8888/API.php"]];

    [request setHTTPMethod:@"POST"];

[request setValue:[[User sharedUser]connectionsID] forKey:@"songs"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[[[User sharedUser] connections] length]] forHTTPHeaderField:@"Content-Length"];
 [request setHTTPBody: [[User sharedUser] connections]];

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSLog(@"Return DATA contains: %@", [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil]);

In my PHP, I receive it like:

    <?php 

header("Content-Type: application/json");
$headers = array_change_key_case(getallheaders());


include "dbconnect.php";

$songs = json_decode(stripcslashes($_GET["songs"]));
echo json_encode($songs);

However, I am not able to receive data in php. Any help or pointers would be appreciated

EDIT: I switched back to using GET since POST was not helping me. Thank you for any help you may offer

Upvotes: 0

Views: 1411

Answers (3)

Yao Li
Yao Li

Reputation: 2286

AFNetworking 2.0 has AFHTTPSessionManager class with POST method

(NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure;

pass connectionsID into parameters

NSDictionary *params = @{@"connectionsID": [connectionsID copy]};

which can be accessed in PHP

$_POST['connectionsID']

Upvotes: 0

Tijn
Tijn

Reputation: 568

I recommend the widely used AFNetworking library (https://github.com/AFNetworking/AFNetworking). A simple POST request with parameters can be constructed like this:

NSDictionary *p = @{@"foo": @"bar"};
[[AFHTTPRequestOperationManager manager] POST:@"http://example.com/resources.json" parameters:p success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error); 
}];

Upvotes: 0

Rob
Rob

Reputation: 437682

A couple of issues:

  1. You are building a Content-Type of application/json request, but your PHP is trying to read the $_POST['songs']. You should do one or the other (either send raw JSON request, or send application/x-www-form-urlencoded request). Let's assume you just wanted to create simple JSON request (as your Objective-C code is largely doing now). In that case, your PHP should read the raw JSON like so:

    <?php
    
    // be a good citizen and report that we're going to return JSON response
    
    header("Content-Type: application/json");
    
    // get the lower case rendition of the headers of the request
    
    $headers = array_change_key_case(getallheaders());
    
    // extract the content-type
    
    if (isset($headers["content-type"]))
        $content_type = $headers["content-type"];
    else
        $content_type = "";
    
    // if JSON, read and parse it
    
    if ($content_type == "application/json")
    {
        // read it
    
        $handle = fopen("php://input", "rb");
        $raw_post_data = '';
        while (!feof($handle)) {
            $raw_post_data .= fread($handle, 8192);
        }
        fclose($handle);
    
        // parse it
    
        $songs = json_decode($raw_post_data, true);
    }
    else
    {
        // report non-JSON request and exit
    }
    
    // now use that `$songs` variable here
    
    // if you wanted to report it back to the client for debugging purposes, you should
    // recreate JSON response:
    
    $raw_result = json_encode($songs);
    
    // finally, write the body of the response
    
    echo $raw_result;
    
    ?>
    
  2. I would suggest removing the the setValue:forKey: with the @"songs" key in your Objective-C code. Assuming you just wanted to send the raw JSON request like I outlined above, then this is not needed (and, frankly, is the wrong way to send a application/x-www-form-urlencoded request, anyway).

If you intended to make the payload so that you could use $_POST['songs'], then the Objective-C code to do that does not use setValue:forKey:, but consists of manually building a request with a Content-Type of application/x-www-form-urlencoded, and the songs=... would be in the body of the request (and you'd have to use CFURLCreateStringByAddingPercentEscapes to encode the JSON string you'd pass in this request). This is all a bit academic, though, as I think you should stick with the application/json request.

Upvotes: 2

Related Questions