AFNetworking 的问题

Posted

技术标签:

【中文标题】AFNetworking 的问题【英文标题】:Issue with AFNetworking 【发布时间】:2014-04-28 11:53:42 【问题描述】:

我的客户端网络服务向我发送这样的结果:

"login":"EMAIL":"none","ID":"none","NOME":"none"

所以,在 AFN 中不起作用。

但是,如果再有一个结果有效:

"login":["EMAIL":"none","ID":"none","NOME":"none","EMAIL":"none","ID":"none","NOME":"none"]

我的代码:

NSDictionary *paramLogin = [NSDictionary dictionaryWithObjectsAndKeys:_txtEmail.text, @"email",_txtSenha.text, @"senha", nil];

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager GET:@"http://webservice.info" parameters:paramLogin success:^(AFHTTPRequestOperation *operation, id responseObject) 

    NSLog(@"%@" , responseObject );

    for (NSDictionary *retLogin in [responseObject valueForKeyPath:@"login"]) 

        nome  = [retLogin objectForKey:@"nome"];
        email = [retLogin objectForKey:@"email"];


    

 failure:^(AFHTTPRequestOperation *operation, NSError *error) 

    NSLog(@"Error: %@", error);

];

为什么会这样?或者我要做什么?

【问题讨论】:

它以什么方式“不起作用”?显示您正在使用的代码。 【参考方案1】:

有时[responseObject valueForKeyPath:@"login"] 返回数组,有时返回字典。您需要对此进行测试。

id loginValue = [responseObject valueForKeyPath:@"login"];

if ([loginValue isKindOfClass:[NSDictionary class]]) 
    nome  = [loginValue objectForKey:@"nome"];
    email = [loginValue objectForKey:@"email"];
 else if ([loginValue isKindOfClass:[NSArray class]]) 
    for (NSDictionary *retLogin in [responseObject valueForKeyPath:@"login"]) 

        nome  = [retLogin objectForKey:@"nome"];
        email = [retLogin objectForKey:@"email"];


    
 else 
    // ERROR: Unexpected value

当你有 1 个值时,loginValue 是一个 NSDictionary。它包含"EMAIL":"none","ID":"none","NOME":"none"

当你有超过 1 个值时,loginValue 是一个 NSArray。该数组包含[<NSDictionary>, <NSDictionary>]。这些字典中的每一个都包含"EMAIL":"none","ID":"none","NOME":"none"

【讨论】:

【参考方案2】:

问题在于您的 json 数据结构。这是不一致的。

"login":"EMAIL":"none","ID":"none","NOME":"none" 

这里的[responseObject valueForKeyPath:@"login"] 是一个NSDictionary 对象。

但是在这里,

"login":["EMAIL":"none","ID":"none","NOME":"none","EMAIL":"none","ID":"none","NOME":"none"]

这里的[responseObject valueForKeyPath:@"login"]NSArray。所以你的快速枚举有效。

最好的解决方案是让您的 Web 服务开发人员一直发送一个数组,即使“登录”只有一个对象。所以它应该看起来像这样,

"login": ["EMAIL":"none","ID":"none","NOME":"none"]  //notice square brackets

否则,当只有一个对象时,您必须修改代码以检查 NSDictionary 而不是数组。

【讨论】:

【参考方案3】:

我怀疑问题在于您没有保留 AFHTTPRequestOperationManager 对象。

假设这段代码类似于viewDidAppear:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:...];

那么manager将在它有机会完成之前被销毁。

改为添加一个属性并将管理器对象存储在其中:

@interface MyViewController ()
@property (nonatomic) AFHTTPRequestOperationManager *manager;
@end

并使用:

self.manager = [AFHTTPRequestOperationManager manager];
[self.manager GET:...];

【讨论】:

【参考方案4】:

如果您收到这样的响应,请使用以下代码

NSMutableArray *category = [[NSMutableArray alloc]init];
category = [responseObject objectForKey:@"login"];

 for(int i = 0; i < [category count]; i++)
 
    NSDictionary *dic = [category objectAtIndex:i]; 
    nome  = [dic objectForKey:@"nome"];
    email = [dic objectForKey:@"email"];
 

【讨论】:

AFNetworking 不需要此功能。响应数据已经是NSDcitionary responseObject 始终是NSDictionary,该字典中的第一个对象是一个数组。无论哪种方式,都不需要使用 JSON 序列化器,因为 AFNetworking 库已经为您做到了。 是的,他需要将第一个对象存储在数组中,这就是我想说的......我已经编辑了答案

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

AfNetworking 2.0 发布问题

AFNetworking 2.0 对现有项目的更新

无法识别的选择器发送到 UIButton+AFNetworking.h 的实例(UIImageView+AFNetworking 也是)

AFNetworking 3.0 迁移

AFNetworking 修改

如何使用 AFNetworking 设置超时