我如何 POST NSDictionary 中的 NSArray of NSDictionary 没有问题?
How can I POST an NSArray of NSDictionaries inside an NSDictionary without problems?
我知道怎么做,很简单。
问题是它不起作用。
这是我用来 POST 数据的函数:
- (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" : @"notreal@gmail.com", @"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;}]
这太疯狂了!
- 我已经成功地在 MySQL 字段中的字典中保存了具有多个属性的字典数组的 JSON -- 或者简而言之,我正在尝试做的事情这里-- 将 PHP 脚本用于不同的目的并且有效,没问题。
- 我使用相同的 PHP 代码将其保存到 MySQL 字段,因此这不是 PHP 的错误。
- 我使用 AFNetworking 制作的所有其他保存/检索功能都能完美运行。
这个有效:
@[@{@"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;
}
);
}
疯了!
出于某种原因,如果我添加一个额外的属性,它就会崩溃。
这一定是 AFNetworking 错误,因为它毫无意义。
编辑:
我可以:
创建两个 MySQL 字段:websiteTitles、websiteURLs。
将其保存为一个字符串:"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 它会解决问题,但我真的不想这样做,因为我已经用这种方式编写了很多方法。
"query string parameterization is simply not a reliable way of encoding nested data structures. This is why all modern web frameworks have built-in conveniences that automatically decode incoming JSON into parameters." - 马特汤普森
所以,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
设置 application/json content-type 并且期望 JSON 的服务器将成功接受请求参数,而 AFHTTPRequestSerializer
将始终在 header 中包含 text/html content-type,即使您明确设置它也是如此。
我知道怎么做,很简单。
问题是它不起作用。
这是我用来 POST 数据的函数:
- (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" : @"notreal@gmail.com", @"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;}]
这太疯狂了!
- 我已经成功地在 MySQL 字段中的字典中保存了具有多个属性的字典数组的 JSON -- 或者简而言之,我正在尝试做的事情这里-- 将 PHP 脚本用于不同的目的并且有效,没问题。
- 我使用相同的 PHP 代码将其保存到 MySQL 字段,因此这不是 PHP 的错误。
- 我使用 AFNetworking 制作的所有其他保存/检索功能都能完美运行。
这个有效:
@[@{@"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;
}
);
}
疯了!
出于某种原因,如果我添加一个额外的属性,它就会崩溃。
这一定是 AFNetworking 错误,因为它毫无意义。
编辑:
我可以:
创建两个 MySQL 字段:websiteTitles、websiteURLs。
将其保存为一个字符串:"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 它会解决问题,但我真的不想这样做,因为我已经用这种方式编写了很多方法。
"query string parameterization is simply not a reliable way of encoding nested data structures. This is why all modern web frameworks have built-in conveniences that automatically decode incoming JSON into parameters." - 马特汤普森
所以,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
设置 application/json content-type 并且期望 JSON 的服务器将成功接受请求参数,而 AFHTTPRequestSerializer
将始终在 header 中包含 text/html content-type,即使您明确设置它也是如此。