iOS使用NSJSONSerialization在POST请求中发送JSON数据

nin*_*een 3 php post json ios nsjsonserialization

我知道有类似的问题发布,因为我已经阅读了大多数所有这些并且仍然遇到问题.我正在尝试将JSON数据发送到我的服务器,但我不认为正在接收JSON数据.我只是不确定我错过了什么.以下是我的代码......

将数据发送到服务器的方法.

- (void)saveTrackToCloud
{
    NSData *jsonData = [self.track jsonTrackDataForUploadingToCloud];  // Method shown below.
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSLog(@"%@", jsonString);  // To verify the jsonString.

    NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:http://www.myDomain.com/myscript.php] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
    [postRequest setHTTPMethod:@"POST"];
    [postRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [postRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [postRequest setValue:[NSString stringWithFormat:@"%d", [jsonData length]] forHTTPHeaderField:@"Content-Length"];
    [postRequest setHTTPBody:jsonData];

    NSURLResponse *response = nil;
    NSError *requestError = nil;
    NSData *returnData = [NSURLConnection sendSynchronousRequest:postRequest returningResponse:&response error:&requestError];

    if (requestError == nil) {
        NSString *returnString = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
        NSLog(@"returnString: %@", returnString);
    } else {
        NSLog(@"NSURLConnection sendSynchronousRequest error: %@", requestError);
    }
}
Run Code Online (Sandbox Code Playgroud)

方法jsonTrackDataForUploadingToCloud

-(NSData *)jsonTrackDataForUploadingToCloud
{
    // NSDictionary for testing.
    NSDictionary *trackDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"firstValue", @"firstKey", @"secondValue", @"secondKey", @"thirdValue", @"thirdKey", nil];

    if ([NSJSONSerialization isValidJSONObject:trackDictionary]) {

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

        if (error == nil && jsonData != nil) {
            return jsonData;
        } else {
            NSLog(@"Error creating JSON data: %@", error);
            return nil;
        }

    } else {

        NSLog(@"trackDictionary is not a valid JSON object.");
        return nil;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的PHP.

<?php
    var_dump($_POST);
    exit;
?>
Run Code Online (Sandbox Code Playgroud)

我收到的输出NSLog(@"returnString: %@", returnString);是......

returnString: array(0) {
} 
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 6

在PHP中,您将获取$_POST变量,该变量用于application/x-www-form-urlencoded内容类型(或其他标准HTTP请求).但是,如果您正在抓取JSON,则应检索原始数据:

<?php

    // read the raw post data

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

    echo $raw_post_data;
?>
Run Code Online (Sandbox Code Playgroud)

但是,更有可能的是,您希望获取该JSON $raw_post_data,将JSON解码为关联数组($request在下面的示例中),然后$response根据请求中的内容构建关联数组,然后将其编码为JSON和把它返还.我还将设置content-type响应以明确它是JSON响应.作为随机示例,请参阅:

<?php

    // read the raw post data

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

    // decode the JSON into an associative array

    $request = json_decode($raw_post_data, true);

    // you can now access the associative array, $request

    if ($request['firstKey'] == 'firstValue') {
        $response['success'] = true;
    } else {
        $response['success'] = false;
    }

    // I don't know what else you might want to do with `$request`, so I'll just throw
    // the whole request as a value in my response with the key of `request`:

    $response['request'] = $request;

    $raw_response = json_encode($response);

    // specify headers

    header("Content-Type: application/json");
    header("Content-Length: " . strlen($raw_response));

    // output response

    echo $raw_response;
?>
Run Code Online (Sandbox Code Playgroud)

这不是一个非常有用的例子(只是检查,看看是否有关联的值firstKey'firstValue'),但希望它说明了如何解析请求,并创建响应的理念.

其他几个旁边:

  1. 您可能希望包括检查响应的状态代码(因为从NSURLConnection透视图中,一些随机服务器错误,如404 - 未找到页面)将不会被解释为错误,因此请检查响应代码.

    你显然可能想NSJSONSerialization用来解析响应:

    [NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        if (error) {
            NSLog(@"NSURLConnection sendAsynchronousRequest error = %@", error);
            return;
        }
    
        if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
            NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
            if (statusCode != 200) {
                NSLog(@"Warning, status code of response was not 200, it was %d", statusCode);
            }
        }
    
        NSError *parseError;
        NSDictionary *returnDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
        if (returnDictionary) {
            NSLog(@"returnDictionary = %@", returnDictionary);
        } else {
            NSLog(@"error parsing JSON response: %@", parseError);
    
            NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"returnString = %@", returnString);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我可能会建议您使用sendAsynchronousRequest,如上所示,而不是同步请求,因为您永远不应该从主队列执行同步请求.

  3. 我的示例PHP正在Content-type对请求等进行最少的检查.因此,您可能希望进行更强大的错误处理.