AFNetworking 数据参数为 nil JSON 数据

Posted

技术标签:

【中文标题】AFNetworking 数据参数为 nil JSON 数据【英文标题】:AFNetworking Data Parameter is nil JSON Data 【发布时间】:2015-03-26 12:31:10 【问题描述】:

我有一个 UITableViewController,我正在尝试使用此代码从 url 获取 JSON 数据,但出现错误。我该怎么办?

  AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
        [securityPolicy setAllowInvalidCertificates:YES];

        NSString *urlPath = [NSString stringWithFormat:@"http://testurl.com/api/index.php"];
        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

        NSDictionary *parameters = @@"process":@"search_customer",@"page": @"";
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

        [manager setSecurityPolicy:securityPolicy];
        manager.responseSerializer = [AFHTTPResponseSerializer serializer];

        [manager POST:urlPath parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) 
            NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

            NSData *jsonData = [NSData dataWithContentsOfFile:string];
            NSError *error = nil;
            NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
            self.customerCards = [NSMutableArray array];
            NSArray *customersArray = [dataDictionary objectForKey:@"musteri_list"];
            for (NSDictionary *customersDictionary in customersArray) 
                ApiClass *customer = [ApiClass customersWithTitle:[customersDictionary objectForKey:@"adi"]];
                customer.tel = [customersDictionary objectForKey:@"tel"];

                [self.customerCards addObject:customer];
            

            NSLog(@"GET: %@", string);
            NSLog(@"POST: %@", parameters);
         failure:^(AFHTTPRequestOperation *operation, NSError *error) 
            NSLog(@"Error: %@", error);
        ];

这是错误块

2015-03-26 14:27:37.656 SaphiraCrm[13770:3881729] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'

【问题讨论】:

你假设 [dataDictionary objectForKey:@"musteri_list"];存在。如果您没有有效的 dataDictionary,则该行下的所有代码都会导致崩溃。所以在开始使用循环条件之前验证字符串、jsonData、dataDictionary 等是否有效。 另外你为什么不使用AFJSONResponseSerializer直接获取JSON。 尝试使用断点调试它并准确检查它崩溃的位置。 【参考方案1】:

我认为问题可能在于您将responseObject 视为NSData,但根据AFNetworking examples,默认情况下AFHTTPRequestOperationManagerresponseSerializerAFJSONResponseSerializer,所以responseObject 已经是一个已解析的 JSON,表示为 NSDictionary(取决于序列化程序)。

因此,这条线

NSString *string = [[NSString alloc] initWithData:responseObject
                                         encoding:NSUTF8StringEncoding];

返回nil,这会导致下一行

NSData *jsonData = [NSData dataWithContentsOfFile:string];

引发异常。

我建议您检查 responseObject 是否符合您的预期并相应地重构您的代码。

...

[manager POST:urlPath 
   parameters:parameters 
      success:^(AFHTTPRequestOperation *operation, id responseObject) 
          if (responseObject) 
              NSLog(@"Response is a %@ and contains: %@", [responseObject class], responseObject);
              // Process responseObject according to its type

...

注意: 以上很可能只是您之前设置串行器配置方式错误的结果,因为您首先设置了acceptableContentType,然后用默认设置覆盖它。

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
...
manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 
// this is likely to invalidate the previous, since you overwritting
// the manager's serializer with a new one with default configuration.

【讨论】:

【参考方案2】:

好吧,我想出了我该怎么做。

这是我的代码

AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
    [securityPolicy setAllowInvalidCertificates:YES];


    NSString *urlPath = [NSString stringWithFormat:@"http://test.com/api/index.php"];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    NSDictionary *parameters = @@"process":@"search_customer",@"page": @"";
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

    [manager setSecurityPolicy:securityPolicy];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager POST:urlPath parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) 
        NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSError *error = nil;
        NSData *jsonData = [string dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];

        self.customerCards = [NSMutableArray array];
        NSArray *customersArray = [dataDictionary objectForKey:@"musteri_list"];
        NSLog(@"%@",customersArray);
        for (NSDictionary *customersDictionary in customersArray) 
            ApiClass *customer = [ApiClass customersWithTitle:[customersDictionary objectForKey:@"adi"]];
            customer.tel = [customersDictionary objectForKey:@"tel"];

            [self.customerCards addObject:customer];

        
        [self.tableView reloadData];

        NSLog(@"GET: %@", string);
     failure:^(AFHTTPRequestOperation *operation, NSError *error) 
        NSLog(@"Error: %@", error);
    ];

【讨论】:

以上是关于AFNetworking 数据参数为 nil JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

我可以让 AFNetworking 自动将 NULL 解析为 nil 吗?

AFNetworking 将参数作为表单数据发送

AFNetworking 未在块内同步返回数据

AFNetworking 获取 XML 解析错误的数据

AFNetworking 上传带参数的图片

iOS开发——Reachability和AFNetworking判断网络连接状态