Asked  1 Year ago    Answers:  5   Viewed   17 times

I've been struggling with this for the last few days; I am trying to post an array to PHP. I can successfully send it, but it's not taken in with a post-variable (I am trying to use the variable key "json"... With this code, I receive the array in php:

Objective-C

NSError *error;
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects: @"one", @"two", @"three", nil] forKeys: [NSArray arrayWithObjects: @"a", @"b", @"c", nil]];
NSArray *jsonArray = [NSArray arrayWithObject:jsonDictionary];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonArray options:NSUTF8StringEncoding error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"somewebservicelocation/arrayTest.php?json="]];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:jsonData];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"response: %@",response);

PHP

$handle = fopen('php://input','r');
    $array = fgets($handle);
    echo $array;
    if(isset($array))
    {
        echo "success";
    }
    else
    {
        echo "failure";
    }

If I use this PHP, using _POST, I get no love:

$rawJsonData = $_POST['json'];
$array = json_decode(stripslashes($rawJsonData),true);
echo $array;
if(isset($array))
{
    echo "success";
}
else
{
    echo "failure";
}

...I've been at it for several days - all over Stack Overflow, and understand I need to include the variable and data in the body of the request, but I just can't get it to work. What am I doing wrong? How do you go about this differently? Save me from this headache...

 Answers

3

On the PHP side, I've used something similar to your first example:

<?php

$handle = fopen("php://input", "rb");
$http_raw_post_data = '';
while (!feof($handle)) {
    $http_raw_post_data .= fread($handle, 8192);
}
fclose($handle);

// do what you want with it
//
// For diagnostic purposes, I'm just going to decode, make sure I got an array, 
// and respond with JSON that includes status, code, and the original request

$post_data = json_decode($http_raw_post_data,true);

if (is_array($post_data))
    $response = array("status" => "ok", "code" => 0, "original request" => $post_data);
else
    $response = array("status" => "error", "code" => -1, "original_request" => $post_data);

$processed = json_encode($response);
echo $processed;

?>

And then on the iOS side, I use:

// create the dictionary (or array)

NSDictionary *dictionary = @{@"a": @"One", @"b": @"Two", @"c": @"Three"};
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
if (error)
    NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error);

// create the request

NSURL *url = [NSURL URLWithString:@"your.url.here"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:data];

// issue the request

NSURLResponse *response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
    NSLog(@"%s: NSURLConnection error: %@", __FUNCTION__, error);

// examine the response

NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"responseString: %@",responseString);

I just tested this round trip, and it works fine.


If you are determined to use the _POST technique, what works for me is to set the the data to be json=%@, such as:

NSDictionary *dictionary = ...
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (error)
    NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error);

NSURL *url = [NSURL URLWithString:@"your.url.here"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"POST"];
NSString *params = [NSString stringWithFormat:@"json=%@",
                    [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *paramsData = [params dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"];
[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:paramsData];

// now send the request, like before

And the PHP to parse it is much like you had:

$http_raw_post_data = $_POST['json'];

$post_data = json_decode(stripslashes($http_raw_post_data),true);

if (is_array($post_data))
    $response = array("status" => "ok", "code" => 0, "original request" => $post_data);
else
    $response = array("status" => "error", "code" => -1, "original_request" => $post_data);

$processed = json_encode($response);
echo $processed;
Thursday, April 1, 2021
 
tplaner
 
5

Now i've solved it by myself =)

I forgot the backslashes in the body.

Here is the right body:

NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"rn--%@rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="uploadedfile"; filename="test.png"rn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-streamrnrn"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"rn--%@--rn",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
Thursday, April 1, 2021
 
ajaybc
 
1

If you're looking for speed, take a look at JSONKit. It is (usually) much faster than the already mentioned JSON libraries, often an order of magnitude faster. And because of it's "recently instantiated object cache", it will (again, usually) use less memory as well.

Wednesday, June 2, 2021
 
Andres
 
4

Try this

 NSString *Post = [[NSString alloc] initWithFormat:@"Post Parameters"];
    NSURL *Url = [NSURL URLWithString:@"Url"];

    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/json" forHTTPHeaderField:@"Accept"];
    [Request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [Request setHTTPBody:PostData];
Friday, August 20, 2021
 
4

I'm not sure which version of the json-framework you are using, but I modified the code to print the offending character:

In SBJSONParser.m:

- (BOOL)scanValue:(NSObject **)o
{
...
default:
[self addErrorWithCode:EPARSE description:[NSString stringWithFormat:@"Unrecognised leading character (%x)", c[-1]]];
//[self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
return NO;
}

You might try setting a breakpoint at that line of code instead.

Also, in general, you can try pasting the JSON into JSONLint at http://jsonlint.com/ to see if it validates. Your JSON does validate, though, so your problem is elsewhere.

Monday, December 13, 2021
 
mc110
 
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :