Reputation: 1126
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
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
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
Reputation: 437682
A couple of issues:
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;
?>
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