服务器接口返回非JSON数据时AFNetworking的异常抛出和正确配置

我们使用AFNetworking时常用的解析器是AFJSONResponseSerializer,这样可以在block中直接得到字典或数组对象,因为AFNetworking已经帮我们序列化好了,我们可以直接使用。
但是在一些情况下AFN会抛出异常,如-10163840的错误,这个时候必须对服务器响应和AFN进行分析。

常用的AFN配置代码类似于:

@interface XLHTTPSessionManager : AFHTTPSessionManager
+(instancetype)defaultManager;
-(void)configCommonHttpHeaders:(NSDictionary *)headers;
@end

@implementation XLHTTPSessionManager
+(instancetype)defaultManager{
    XLHTTPSessionManager *manager = [self manager];
    if (!manager) {
        return manager;
    }
    AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
    response.removesKeysWithNullValues = YES;
    [manager setResponseSerializer:response];
    [manager setRequestSerializer:[AFJSONRequestSerializer serializer]];
    manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    
    return manager;
}
@end

使用时是这样的:

XLHTTPSessionManager *manager = [XLHTTPSessionManagerdefaultManager];
[managerGET:url parameters:paramDic success:^(NSURLSessionDataTask *task, id responseObject) {
         NSDictionary *responseDic = responseObject;

} failure:^(NSURLSessionDataTask *task, NSError *error) {
       
}];

该配置会将服务器响应当作json来处理,AFNetworking会以json的形式去解析,将服务器返回数据解析成一个字典或数组。
如果服务器返回json格式的数据,AFNetworking的序列化器会解析成功;但如果服务器返回xlm或html或其它无意义字符串,AFN无法解析得到字典或数组对象从而抛异常。实际上请求是成功的,只是用AFJSONResponseSerializer解析器无法解析而已。


AFN抛出异常主要有以下几种情况:

1.报错-1016:

Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response= { URL: } { status code: 200, headers {}

NSLocalizedDescription=Request failed: unacceptable content-type: text/html

2.报错3840:

Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

产生报错的原因,都是由于后台返回的不是一个有效的JSON对象,而AFN以JSON的标准来解析,因为无法正常序列化JSON而抛出了一个error。

解决办法也比较简单,以下是解决思路:

一、AFN默认还是以JSON解析器对服务器返回数据进行JSON序列化,确保服务器返回JSON时能正确解析;在某些接口非常确认服务器响应非JSON时,在代码中重新设置解析器为 AFHTTPResponseSerializer,亦能确保服务器响应为非JSON时可以正确解析。

二、最后回归到代码,看看代码中的具体实现:
解决方法如下:

XLHTTPSessionManager *manager = [XLHTTPSessionManager defaultManager];
manager.responseSerializer = [AFHTTPResponseSerializerserializer];
[manager POST:url parameters:nilsuccess:^(NSURLSessionDataTask *task, id responseObject) {        
        NSString *responseStr = [[NSStringalloc]initWithData:responseObject encoding:NSUTF8StringEncoding];       
        DDLogInfo(@"--------- %@",responseStr);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
       
}];

你可能感兴趣的:(服务器接口返回非JSON数据时AFNetworking的异常抛出和正确配置)