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

我知道还有类似的问题,因为我已经阅读,虽然他们大多数都仍然有问题。 我试图发送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);接收的输出NSLog(@"returnString: %@", returnString); 是…

 returnString: array(0) { } 

在你的PHP中,你正在抓取$_POSTvariables,这个variables是application/x-www-form-urlencoded内容types(或其他标准的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 ,在我的例子中),然后根据请求中的内容构build一个关联数组$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; ?> 

这不是一个非常有用的例子(只是检查与firstKey相关的值firstKey'firstValue' ),但希望它能说明如何parsing请求并创build响应的想法。

其他一些旁白:

  1. 你可能想要包括对响应状态码的检查(因为从NSURLConnectionangular度来看,一些随机的服务器错误,如404页面没有find)不会被解释为错误,所以检查响应代码。

    你显然可能想要使用NSJSONSerialization来parsing响应:

     [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); } } 
  2. 我可能会build议你应该使用sendAsynchronousRequest ,如上所示,而不是同步请求,因为你不应该从主队列中做同步请求。

  3. 我的例子PHP是做最小的请求的Content-type检查等,所以你可能想要做更强大的error handling。

高级rest客户端可以方便地testing您的Web服务。 因此,确保Web服务按照需要进行操作,然后在客户端应用程序中映射相同的参数。