У меня есть ситуация, когда я помещаю строку JSON из своего кода iOS, используя код AFNetworking 2.0. Мой клиентский код выглядит так:
NSURL *url = [NSURL URLWithString:BaseURLString];
NSString *jsonString = [[NSString alloc] initWithData:jsonPayloadForProject encoding:NSUTF8StringEncoding];
NSDictionary *parameters = @{@"project": jsonString};
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
[manager POST:@"service.php" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"%@", [responseObject description]);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"POST JSON for Project Error"message:[error localizedDescription]
delegate:nil
cancelButtonTitle:@"OK"otherButtonTitles:nil];
[alertView show];
}];
JSON выглядит так:
{
"Maps" : [
{
"Markers" : [
{
"marker_tag" : -790386438,
"location_y" : 182,
"location_x" : 344
},
{
"marker_tag" : 451496476,
"location_y" : 267,
"location_x" : 150.5
}
],
"image_string" : "EC817509-DE49-4914-840E-5E407571F6AE.jpeg",
"order_num" : 0,
"name" : "Blah1",
"id" : "EC817509-DE49-4914-840E-5E407571F6AE"},
{
"Markers" : [
{
"marker_tag" : -79601351,
"location_y" : 377,
"location_x" : 486.5,
"image_id" : "Blah2",
"map_id" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A"}
],
"image_string" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A.jpeg",
"order_num" : 0,
"name" : "1st floor",
"id" : "146C1C09-5AE0-4E4C-83C8-B7EAA8F28A9A"}
],
"longitude" : "-222.222222",
"latitude" : "33.33333"}
Когда я читаю строку JSON на сервере в своем PHP-коде, используя
$json_str = file_get_contents('php://input');
Когда я это делаю, я получаю следующую строку:
{ "project" = '{ \n \"Maps\" : [ \n { \n \"Markers\" : [ \n { \n \"marker_tag\n : = -790386438, \n ....
Мой вопрос заключается в том, что, когда я делаю следующее, я ничего не получаю.
$array_str = json_decode($json_str, true);
Каков наилучший способ поместить это в массив для анализа данных? Как я могу получить исходную строку JSON, которую я отправил с моего клиента?
Пара вопросов
Ваш AFHTTPSessionManager
использует по умолчанию AFJSONResponseSerializer
но просто отменяет acceptableContentTypes
, Это можно сделать только в том случае, если код вашего сервера действительно возвращает JSON и не указывает это в Content-Type
заголовок.
Если сервер действительно не возвращает JSON, а не изменяет acceptableContentTypes
, вы должны просто использовать AFHTTPSessionManager
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
или сервер должен вернуть JSON и убедиться, что он указывает правильное Content-Type
заголовок:
<?php
$json_str = file_get_contents('php://input');
$json = json_decode($json_str, true);
header('Content-Type: application/json');
$result = array("received" => $json);
echo json_encode($result);
?>
Сделав это, теперь я могу просто удалить acceptableContentTypes
строка из клиентского кода в целом и продолжать использовать значение по умолчанию AFJSONResponseSerializer
,
Продемонстрированный механизм построения parameters
это неверно. Вы создаете словарь JSON только с одним элементом, который сам по себе является строковым представлением JSON.
Вместо того, чтобы помещать строковое представление в словарь, я бы посоветовал вам поместить в словарь реальный словарь. Итак, если у вас действительно есть NSData
JSON, преобразовать его обратно во вложенный NSDictionary
/NSArray
состав:
NSError *error;
id jsonPayload = [NSJSONSerialization JSONObjectWithData:jsonPayloadData options:0 error:&error];
NSAssert(jsonPayload, @"json parsing error: %@", error);
NSDictionary *parameters = @{@"project": jsonPayload};
Теперь, скорее всего, будет немного глупо создавать NSData
с помощью dataWithJSONObject
только чтобы развернуться и извлечь его обратно, а вы бы просто использовать этот оригинал NSDictionary
в parameters
, но, надеюсь, это иллюстрирует суть.
Итак, собрав все это вместе, предполагая, что вы измените код сервера, чтобы он возвращал правильно отформатированный ответ JSON, как описано выше, клиентский код теперь становится:
NSError *error;
id jsonPayload = [NSJSONSerialization JSONObjectWithData:jsonPayloadData options:0 error:&error];
NSAssert(jsonPayload, @"json parsing error: %@", error);
NSDictionary *parameters = @{@"project": jsonPayload};
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
[manager POST:@"service.php" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"%@", [responseObject description]);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"error=%@", error);
}];
Если вы сделаете это, вы успешно отправите свой JSON-запрос на сервер, он будет проанализирован, вставлен в новый ассоциативный массив, преобразован обратно в JSON и возвращен в клиентское приложение, которое будет использовать значение по умолчанию. AFJSONResponseSerializer
разобрать и записать.
Других решений пока нет …