AFNetworking 将 NSDictionary 作为单个数组值发送,而不是作为完整对象发送
Posted
技术标签:
【中文标题】AFNetworking 将 NSDictionary 作为单个数组值发送,而不是作为完整对象发送【英文标题】:AFNetworking sending NSDictionary as single array values instead of sending them as complete objects 【发布时间】:2013-09-09 18:09:43 【问题描述】:我正在尝试发送一个NSArray *appData
,因为它是一个包含NSDictionary
的NSArray
(请参阅下面的数据布局)但是当我在@987654325 中收到Array
@NSDictionary
中的所有值都作为单个数组发送,并且与发送时的格式不同(请参阅下面的 php 日志数据)。
NSDictionary* params
中的所有其他值都可以正确发送和接收。
这是我的代码中的错误还是问题?如果后者是问题,我做错了什么?
注意:我使用的是最新版本的AFNetworking
编辑:
作为@dpassage
答案的结果,我进行了编辑以包含更广泛的测试并将信息作为form-data
发送。测试的有趣之处在于,发送到服务器的@"test"
参数在PHP
中显示得很好,但@"share":appData
却没有,这很奇怪
- (void) checkForUploadEligibility
NSArray* dates = [myModel getStatsMaxAndMinResults];
if ( dates )
NSDictionary* d = [dates objectAtIndex:0];
NSDate* minDate = d[@"minDate"];
NSDate* maxDate = d[@"maxDate"];
NSTimeInterval secondsBetween = [maxDate timeIntervalSinceDate:minDate];
int numberOfDays = secondsBetween / 86400;
numberOfDays = abs(numberOfDays);
if (numberOfDays >= 0)
myUser = [myModel getCurrentUser];
if ( myUser.userWebID && myUser.authToken )
NSArray* appData = [myModel getAllStatsData];
if (!appData)
return;
NSDictionary* params = @ @"userID": myUser.userWebID,
@"authCode": myUser.authToken,
@"interact":@@"action":@"uploadAppStats",
@"actionTarget":@"uploadAppStats",
@"share":appData,
@"test":@[@@"test1":@@"test2":@"test2",@@"test3":@"test3"]
;
[myShare uploadStats:params statsData:appData];
- (void) uploadStats:(NSDictionary*)params statsData:(NSArray *)statsData
NSLog(@"count %i, %@",[statsData count],statsData);
NSURL *url = [[NSURL alloc]initWithString:sysURL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:url];
NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:sysAppURLPath parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
NSLog(@"a: Inside the success block %@",JSON);
if ( [JSON objectForKey:@"ok"] )
// [myModel deleteAllStatsData:statsData];
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
NSLog(@"json text is: %@", JSON);
NSLog(@"Request failed with error: %@, %@", error, error.userInfo);
];
// Debug HTTP response
BOOL dbug = YES;
if (dbug)
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
NSLog(@"HTTP r: %@", operation.responseString);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"HTTP Error: %@", operation.responseString);
];
[operation start];
错误日志
count 5, (
date = "2013-09-09 16:10:51 +0000";
name = selectRoutine;
shared = 0;
timeSpent = 3;
,
date = "2013-09-09 16:10:53 +0000";
name = manageExercises;
shared = 0;
timeSpent = 1;
, // MORE.....
HTTP Error: array(24)
multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY
array(5)
["authCode"]=>
string(32) "e186cdd000a741ef76555009d7e86d80"
["interact"]=>
array(2)
["action"]=>
string(14) "uploadAppStats"
["actionTarget"]=>
string(14) "uploadAppStats"
["share"]=>
array(15)
[0]=>
array(1)
["date"]=>
string(19) "2013-09-09 19:52:31"
[1]=>
array(1)
["name"]=>
string(13) "selectRoutine"
[2]=>
array(1)
["timeSpent"]=>
string(1) "3"
[3]=>
array(1)
["date"]=>
string(19) "2013-09-09 19:52:33"
[4]=>
array(1)
["name"]=>
string(14) "manageRoutines"
[5]=>
array(1)
["timeSpent"]=>
string(1) "2"
[6]=>
array(1)
["date"]=>
string(19) "2013-09-09 22:24:31"
[7]=>
array(1)
["name"]=>
string(13) "selectRoutine"
[8]=>
array(1)
["timeSpent"]=>
string(2) "19"
[9]=>
array(1)
["date"]=>
string(19) "2013-09-09 22:24:45"
[10]=>
array(1)
["name"]=>
string(14) "manageRoutines"
[11]=>
array(1)
["timeSpent"]=>
string(2) "14"
[12]=>
array(1)
["date"]=>
string(19) "2013-09-09 22:25:58"
[13]=>
array(1)
["name"]=>
string(15) "manageExercises"
[14]=>
array(1)
["timeSpent"]=>
string(2) "73"
["test"]=>
array(2)
[0]=>
array(1)
["test1"]=>
array(1)
["test2"]=>
string(5) "test2"
[1]=>
array(1)
["test3"]=>
string(5) "test3"
["userID"]=>
string(24) "5224b598f86f265801000008"
【问题讨论】:
【参考方案1】:问题:
插入到@"share":appData
中的NSArray* appData
以某种方式被转换为大量小数组。
解决办法:
如果我在Key-Value NSDictionary @"share"
中插入NSArray
,它不会按预期工作。然后我继续将 NSArray
更改为 NSDictionary
也不起作用。
下面的代码起作用了。我不得不将NSArray* appData
重新创建为NSDictionary* appData2
。然后我必须将每个人 NSDictionary data object
包装到另一个 NSDictionary
中,但我必须给这个新对象一个显式数字索引...之后它会正确发送信息.
我猜我的问题是一个错误?我真的不知道......但如果有人也有问题,这可以帮助你。
NSArray* appData = [myModel getAllStatsData];
if (!appData)
return;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: @"yyyy-MM-dd HH:mm:ss"];
NSMutableDictionary* choa = [[NSMutableDictionary alloc]init];
int i = 0;
for (StatsAppUsage*statObj in appData)
[choa addEntriesFromDictionary:@[NSNumber numberWithInteger:i]:@@"date":[dateFormat stringFromDate:statObj.date],
@"name":statObj.name,
@"timeSpent": statObj.timeSpent
];
i++;
NSDictionary* appData2 = [[NSDictionary alloc]initWithDictionary:choa];
NSDictionary* params = @ @"userID": myUser.userWebID,
@"authCode": myUser.authToken,
@"interact":@@"action":@"uploadAppStats",
@"actionTarget":@"uploadAppStats",
@"share":appData2
;
@"share" PHP 输出
(
[0] => Array
(
[date] => 2013-09-09 19:52:31
[name] => selectRoutine
[timeSpent] => 3
)
[1] => Array
(
[date] => 2013-09-09 19:52:33
[name] => manageRoutines
[timeSpent] => 2
)
【讨论】:
我只是用这个答案来解决我的问题。非常感谢。即使在我遵循您的解决方案之后,让我陷入困境的一件事是将参数编码设置为AFFormURLParameterEncoding
而不是AFJSONParameterEncoding
的必要步骤。也许在您的答案中突出显示这一点将对未来的读者有很大帮助。 :)【参考方案2】:
我认为问题的出现是因为您使用带有参数的默认 HTTP POST 来发送您的值。您可以通过在服务器端打印出帖子的内容类型来确认这一点;它应该类似于x-www-form-urlencoded
。如果是这样的话,这种数据格式就不能真正很好地表达数组和字典。所以你得到了你在服务器端看到的奇怪格式。
您可能想要做的是将数据作为 JSON 发送,而不是作为纯格式参数发送。我相信您要做的是将AFHTTPClient
的parameterEncoding
属性设置为AFJSONParameterEncoding
。这会将您的请求以 JSON 格式发送,它能够在线上正确地表示数组和字典。
【讨论】:
它说当我做print_r($_SERVER["CONTENT_TYPE"]);
我得到application/x-www-form-urlencoded
但我将脚本修改为NSURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST" path:sysAppURLPath parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) ];
现在我得到multipart/form-data
但同样的错误
我也试过httpClient.parameterEncoding = AFJSONParameterEncoding;
,我可以看到CONTENT_TYPE
为application/json
,但我尝试了var_dump($_REQUEST)和$_POST,但都显示为空以上是关于AFNetworking 将 NSDictionary 作为单个数组值发送,而不是作为完整对象发送的主要内容,如果未能解决你的问题,请参考以下文章