美文网首页BUGs
[AFN]使用AFNetworking遇到的问题总结

[AFN]使用AFNetworking遇到的问题总结

作者: 流火绯瞳 | 来源:发表于2016-11-09 08:36 被阅读3153次

    1. The data couldn’t be read because it isn’t in the correct format

    这个问题是使用AFN发送POST请求时遇到的,奇怪的是使用GET请求能够正常拿到数据,而使用POST就不行;
    控制台输出如下信息:

    http://192.168.69.121:8080/artboss-webapp/ios/checkcode  
     params:{  
        "user_phonenumber" = 185****0925;  
    }  
     errorInfos:The data couldn’t be read because it isn’t in the correct format.  
    

    大意就是数据没有正确的被格式化,无法读取!后台也接收不到我传递的参数;
    使用Charles抓包会发现是这样的信息:

    HTTP Status 400 - Request String parameter 'user_phonenumber' is not present  
    

    400 Bad Request!

    我一看是非法的网络请求,以为是我的问题,就一直在我这边找原因,
    最后才发现,这是因为我发送请求时发送的字符串,和后台需要的字符串格式不一致,发送请求时,后台需要的是text文本格式,而我发送的是json格式,导致后台无法识别,接收不到数据!
    后来发现我所用的封装类里的请求头,有如下设置:

    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];  
    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];  
    

    即,默认是使用json传输数据的!
    把第二个注释掉,即使用默认的Content-Type,
    并在发送请求时设置发送的字段为文本格式,即:

    manager.requestSerializer = [AFHTTPRequestSerializer serializer];  
    

    本以为会解决问题,但事实还是请求不到数据!!
    最后不得已使用原生的AFNetworking进行测试,post正常拿到了数据,后来对比两者的区别,除了上面的改动以外,请求返回的数据也要改为文本,即:

    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 
    

    这样才正常拿到了数据!!
    总之,此次网络请求的异常,是由于请求和响应的文本格式没有统一,导致参数无法正常传递,数据无法正常读取!

    2. Invalid parameter not satisfying: body

    在使用AFNetworking进行传图操作的时候,出现了这个crash信息:
    模拟器运行后控制台输出:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: body'  
    *** First throw call stack:  
    (  
        0   CoreFoundation                      0x0000000107ad4e65 __exceptionPreprocess + 165  
        1   libobjc.A.dylib                     0x0000000106c1edeb objc_exception_throw + 48  
        2   CoreFoundation                      0x0000000107ad4cca +[NSException raise:format:arguments:] + 106  
        3   Foundation                          0x000000010431d4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198  
    )  
    libc++abi.dylib: terminating with uncaught exception of type NSException  
    

    真机的话会输出如下信息:

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: body'  
    *** First throw call stack:  
    (0x225e62eb 0x21db2dff 0x225e61c1 0x22dbcd3b 0x1b8d3f 0x1b8981 0x1909f1 0x1b4a6b 0x1a1be9 0x1906c1 0x176535 0x177171 0x193371 0x18f5cb 0x19fbb9 0x8dfcbf 0x8dfcab 0x8e4771 0x225a8fc5 0x225a74bf 0x224f9bb9 0x224f99ad 0x23773af9 0x267e5fb5 0x118b11 0x221ac873)  
    libc++abi.dylib: terminating with uncaught exception of type NSException  
    (lldb)   
    

    而且crash的地方也不一样:
    模拟器crash到自动释放池

    模拟器crash

    真机的话carsh到AFN的底层:

    真机crash

    其实,最主要的信息就是:Invalid parameter not satisfying: body (无效的参数:body)
    问题就出在body这个参数上,模拟器上看不出什么头绪,请求参数中也没有body这个参数;但是在真机上的crash信息可以看出一些头绪:他是crash到了这个方法里

    - (void)appendPartWithHeaders:(NSDictionary *)headers  
                             body:(NSData *)body  
    {  
        NSParameterAssert(body);  
      
        AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];  
        bodyPart.stringEncoding = self.stringEncoding;  
        bodyPart.headers = headers;  
        bodyPart.boundary = self.boundary;  
        bodyPart.bodyContentLength = [body length];  
        bodyPart.body = body;  
      
        [self.bodyStream appendHTTPBodyPart:bodyPart];  
    }  
    

    可以看到body的类型是NSData,而设置的请求参数中,只有要发送的照片数据是NSData类型,是不是照片的问题呢?进到AFN的底层可以发现,AFN上传图片主要是用到了这个方法:

    - (void)appendPartWithFileData:(NSData *)data  
                              name:(NSString *)name  
                          fileName:(NSString *)fileName  
                          mimeType:(NSString *)mimeType  
    {  
        NSParameterAssert(name);  
        NSParameterAssert(fileName);  
        NSParameterAssert(mimeType);  
      
        NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary];  
        [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];  
        [mutableHeaders setValue:mimeType forKey:@"Content-Type"];  
      
        [self appendPartWithHeaders:mutableHeaders body:data];  
    }  
    

    在这个方法里调用了

    [self appendPartWithHeaders:mutableHeaders body:data];
    

    正是,程序crash的地方;
    其实,打断点调试后也能发现传入的照片数据为nil,问题的根源找到了,问题也就解决了!!!

    3. terminating with uncaught exception of type NSException

    虽然上面那个问题中也有这句输出,但是这次除了这句没有其他信息,上面的还有其他比较多的信息以供排查问题,这次是这样的:


    什么鬼都看不出来...

    检查了各种参数,都没有问题,最后不得已,断点一步步执行,最后发现是请求时的数据格式问题;
    AFN的默认请求的数据格式为JSON,这也是大多数后台使用的数据格式,同样返回格式也是JSON;
    但是,但是,但是...重要的事情说三遍,总有不支持JSON的后台接口.......
    最后,我设置了一下请求头的请求数据格式,即:

    manager.requestSerializer = [AFHTTPRequestSerializer serializer];  
    

    最后就可以正常发送请求了;
    这也是因为发送请求时的数据格式问题,所以,一定要和后台沟通好, 一定要和后台沟通好, 一定要和后台沟通好....

    相关文章

      网友评论

      • 有理想有暴富的小青年:最近项目中遇到的问题和楼主写的有点相似 回去试一下 我的问题是 也是用afn 别的页面都正常 就有一个明明post上传给后台了 就是在afn的回调中没有接到数据 连错误信息也没有返回 成功和失败block都没有走 直接崩溃到main函数 但是用charles是有返回加密数据的 这就很蛋疼了

      本文标题:[AFN]使用AFNetworking遇到的问题总结

      本文链接:https://www.haomeiwen.com/subject/yyyouttx.html