Я знаю, как это сделать, это довольно просто.
Проблема в том, что это не работает.
Вот функция, которую я использую для размещения данных:
- (void)updateWebsitesUsingParameters:(NSDictionary *)parameters;
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:@"http://notreal/updateWebsites.php"parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
//...
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//...
}];
}
Вот параметры:
NSDictionary *parameters = @{@"type" : @"0",
@"credentials" : @{@"email" : @"[email protected]", @"password" : @"notreal"},
@"device" : @{@"ID" : @"8588107756600540", @"numberOfSessions" : @"0", @"name" : @"Nick's iMac"},
@"websites" : @[@{@"title" : @"Google", @"URL" : @"http://www.google.com"}, @{@"title" : @"Yahoo", @"URL" : @"http://www.yahoo.com"}]};
Вот что сохраняется в поле MySQL:
[{URL = "http://www.google.com";},{title = Google;},{URL = "http://www.yahoo.com";},{title = Yahoo;}]
ЭТО БЕЗУМИЕ!
Это работает:
@[@{@"title" : @"Google"}, @{@"title" : @"Yahoo"}]
Это не:
@[@{@"title" : @"Google", @"URL" : @"http://www.google.com"}, @{@"title" : @"Yahoo", @"URL" : @"http://www.yahoo.com"}]
Вот ответ:
{
websites = (
{
URL = "http://www.google.com";
},
{
title = Google;
},
{
URL = "http://www.yahoo.com";
},
{
title = Yahoo;
}
);
}
INSANE!
По какой-то причине он ломается, если я добавляю дополнительный атрибут.
Это должно быть AFNetworking ошибка, потому что это не имеет смысла.
РЕДАКТИРОВАТЬ:
Я мог бы:
Сделайте два поля MySQL: websiteTitles, websiteURL.
Сохраните его как одну строку: «Google;http://www.google.com«, а затем отделить его, но это противоречит цели использования JSON.
Отправьте параметры разделенными пополам: websteTitles, websiteURLs
Все отвратительно, есть идеи?
РЕДАКТИРОВАТЬ 2:
Я провожу несколько тестов:
Не имеет значения, содержит ли массив 1 или 2 элемента, он все еще ведет себя так.
Я пробовал что rob180 предложил и — как и ожидалось — это вина AFNetwokring:
{
websites = (
{
URL = "http://www.google.com";
},
{
title = Google;
},
{
URL = "http://www.yahoo.com";
},
{
title = Yahoo;
}
);
}
Это фактический ответ сервера на то, что было отправлено из приложения, в середине нет mysql.
РЕДАКТИРОВАТЬ 3:
REQUEST: <NSMutableURLRequest: 0x7f9352d467e0> { URL: http://notreal/updateWebsites.php }
HTTPBody выглядит так:
<63726564 656e7469 616c735b ... 653d30>
Как я могу расшифровать это?
Кроме того, я использую AFHTTPRequestSerializer. Может быть, если я изменю это на AFJSONRequestSerializer это решит проблему, но я действительно не хочу, так как я написал много методов таким образом.
«Параметризация строки запроса просто не является надежным способом кодирования вложенных структур данных. Вот почему все современные веб-фреймворки имеют встроенные удобства, которые автоматически декодируют входящий JSON в параметры». — Мэтт Томпсон
Так, JSON это…
Параметры:
NSDictionary *parameters = @{@"websites" : @[@{@"Title" : @"Google", @"URL" : @"http://www.google.com"}, @{@"Title" : @"Yahoo", @"URL" : @"http://www.yahoo.com"}]};
Послать:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:@"http://server/path/file.php"parameters:parameters
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"JSON: %@", responseObject);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"Error: %@", error.description);
}];
Получить:
<?php
header('Content-type: application/json');
$request = json_decode(file_get_contents('php://input'), TRUE);
$response = ["URLOfTheSecondWebsite" => $request['websites'][1]['URL']];
echo json_encode($response);
?>
Отклик:
{
URL = "http://yahoo.com";
}
Все сделано!
Чистое золото.
функция обновления AFQueryStringPairsFromKeyAndValue
менять
for (id nestedValue in array) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];
}
в
int i = 0;
for (id nestedValue in array) {
[mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[%d]", key, i++], nestedValue)];
}
Была такая же проблема с AFHTTPSessionManager
,
К сожалению, вы должны переключиться на AFJSONRequestSerializer
отправить массив словарей:
manager.requestSerializer = [AFJSONRequestSerializer serializer];
AFJSONRequestSerializer
наборы Применение / JSON Тип содержимого и сервер, который ожидает, что JSON успешно примет параметры запроса, в то время как AFHTTPRequestSerializer
всегда будет иметь текст / html content-type в заголовке, даже если вы установили его явно.