在 AFJSONRequestOperation 中接受无效的 JSON?
Posted
技术标签:
【中文标题】在 AFJSONRequestOperation 中接受无效的 JSON?【英文标题】:Accepting invalid JSON in an AFJSONRequestOperation? 【发布时间】:2013-11-13 21:52:50 【问题描述】:我正在修复现有项目中的错误。问题是 AFHTTPClient 期望一个有效的 JSON 响应,但是服务器返回一些像 ""\" Operation complete\"" 之类的乱码(所有引号和括号都在返回中)。这导致操作失败,并命中失败块,因为它无法解析响应。尽管如此,服务器正在返回状态码 200,并且很高兴操作完成。
我有一个像这样扩展 AFHTTPClient 的类(从我的 .h 文件中提取)
@interface AuthClient : AFHTTPClient
//blah blah blah
@end
在我的实现文件中,类的初始化如下:
- (id)initWithBaseURL:(NSURL *)url
if (self = [super initWithBaseURL:url])
self.parameterEncoding = AFFormURLParameterEncoding;
self.stringEncoding = NSASCIIStringEncoding;
[self setDefaultHeader:@"Accept" value:@"application/json"];
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
return self;
我正在拨打的电话是在上面提到的课程中完成的,并且发生的情况如下:
- (void)destroyToken:(NSString *)token onCompletion:(void (^)(BOOL success))completion onFailure:(void (^)(NSError *error))failure
[self postPath:@"TheServerURL" parameters:@@"token": token success:^(AFHTTPRequestOperation *operation, id responseObject)
NSError *error;
//Do some stuff
failure:^(AFHTTPRequestOperation *operation, NSError *error)
//Don't want to be here.
];
在失败块中,错误对象的 _userInfo 部分将返回错误:
[0] (null) @"NSDebugDescription" : @"JSON 文本没有以数组或对象开头,并且允许未设置片段的选项。"
错误码是3480。
通过谷歌搜索,我发现我需要设置类似 NSJSONReadingAllowFragments 的内容,但我不确定当前设置的方式/位置。有人有什么想法吗?
【问题讨论】:
当服务端响应一个无效的JSON,为什么服务不固定? 服务器修复已安排,但暂时不会推送。这超出了我的控制范围。但是,它正在影响我的测试计划。 【参考方案1】:听起来响应根本不是 JSON。那么,为什么不直接接受 HTTP 响应本身,而不是尝试像 JSON 一样处理它呢?
如果您正在提交 JSON 格式的请求,但只想返回文本响应,则使用 AFNetworking 2.0 您可以执行以下操作:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager POST:urlString parameters:@@"token":token success:^(AFHTTPRequestOperation *operation, id responseObject)
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"responseString: %@", string);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
或者,在 1.x 中:
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
client.parameterEncoding = AFJSONParameterEncoding;
NSMutableURLRequest *request = [client requestWithMethod:@"POST" path:path parameters:@@"token" : token];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"response: %@", string);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Error: %@", error);
];
[client enqueueHTTPRequestOperation:operation];
【讨论】:
我更愿意按照你的建议去做,但这是一个大类,它的工作率为 98%。这只是返回无效 JSON 的一个端点。重构整个课程需要通过 QA 进行大量返回,因此目前这不是一个选择。不过,感谢您的出色回应。在 99% 的情况下,这将是完美的反应!我知道我的情况是极端情况。 @Rob(我觉得我是在自言自语:)明白(尽管我没有真正解决您的问题,但感谢您的接受)。您能否将您的课程更改为始终使用AFHTTPRequestOperation
,然后调用JSONObjectWithData
,如果调用成功则返回JSON 对象,否则返回NSData
?似乎不会破坏其余代码的潜在更改。显然,正如 CouchDeveloper 建议的那样,最好的解决方案是修复 Web 服务以返回 JSON(可能有条件地这样做,检查请求的 Accept
参数以确保向后兼容,如果需要)。以上是关于在 AFJSONRequestOperation 中接受无效的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章
AFJSONRequestOperation 不更新块外的内容
如何从 AFNetworking 和 AFJSONRequestOperation 获得可变字典?