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

时间:2014-03-05 05:00:37

标签: php ios json post 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);
    }
}

方法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;
    }
}

这是我的PHP。

<?php
    var_dump($_POST);
    exit;
?>

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

returnString: array(0) {
} 

2 个答案:

答案 0 :(得分: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;
?>

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

content-type

这不是一个非常有用的示例(仅检查与<?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; ?> 相关联的值是否为firstKey),但希望它说明了如何解析请求并创建响应的想法

其他几个旁白:

  1. 您可能希望包括检查响应的状态代码(从'firstValue'的角度来看,某些随机服务器错误,如404 - 找不到页面)不会被解释为错误,所以检查响应代码。

    您显然可能希望使用NSURLConnection来解析响应:

    NSJSONSerialization
  2. 我可能建议您使用[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); } } ,如上所示,而不是同步请求,因为您永远不应该从主队列执行同步请求。

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

答案 1 :(得分:0)

Advanced Rest Client可以方便地测试您的网络服务。因此,请确保Web服务按预期运行,然后在客户端应用程序中映射相同的参数。