AFNetworking将NSDictionary作为单个数组值发送,而不是将它们作为完整对象发送

时间:2013-09-09 18:09:43

标签: ios objective-c cocoa-touch afnetworking

我正在尝试发送NSArray *appData,因为它是NSArray,其中包含NSDictionary请参阅下面的数据布局)但是当我收到Array中的PHP NSDictionary中的所有值都作为单个数组发送,而不是以相同的格式发送(请参阅下面的PHP日志数据)。< / p>

正确发送和接收NSDictionary* params中的所有其他值。

这是我的代码中的错误还是问题?如果后者是问题,我做错了什么?

注意:我使用的是AFNetworking

的laster版本

修改 作为@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"
}

2 个答案:

答案 0 :(得分:2)

问题:

以某种方式插入NSArray* appData

@"share":appData被翻译成多个小数组。

解决方案:

如果我向NSArray插入Key-Value NSDictionary @"share",它就会无法正常工作。然后我继续将NSArray更改为NSDictionary,但也无效。

以下代码的作用是什么。我必须重新NSArray* appDataNSDictionary* 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
                                   };

@“分享”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
        )

答案 1 :(得分:0)

我认为问题的出现是因为您使用带参数的默认HTTP POST来发送您的值。您可以通过在服务器端打印出帖子的内容类型来确认这一点;它应该是x-www-form-urlencoded的内容。如果是这种情况,那么数据格式就无法真正表达数组和字典。所以你得到了你在服务器端看到的奇怪格式。

您可能想要做的是将数据作为JSON发送,而不是作为普通表单参数发送。我相信您要做的是将parameterEncoding的{​​{1}}属性设置为AFHTTPClient。这将以JSON形式发送您的请求,JSON能够在线路上正确表示数组和字典。