一个AFTHTTPClient可以同时处理json和xml吗?
我有一个域,其中一些服务只返回json,而其他只返回xml。我如何发出GET请求并指示AFHTTPClient对某些服务使用AFJSONRequestOperation,为其他GET请求使用AFXMLRequestOperation?
所以我想要的是:
chairs.com GET customerprofile ---> returns XML (no option for json)
charis.com GET inventory ---> returns JSON (no option for xml)
这是多个AFHTTP客户端的工作吗? 感谢
答案 0 :(得分:7)
您使用AFHTTPClient
表示您正在使用AFNetworking 1,但我会针对这两个版本回答此问题,以供将来的读者使用。
您只需要注册相应的AFHTTPOperation子类。这通常在您的initWithBaseURL:
:
- (instancetype) initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self registerHTTPOperationClass:[AFXMLRequestOperation class]];
}
return self;
}
当您的应用发出传出请求时,您需要确保accept
标头设置正确(例如,text/json
或text/xml
,具体取决于您的预期从哪个端点击中)。否则,AFNetworking将不知道哪个操作用于哪个请求。
有几种方法可以轻松解决此Accept
标头要求。如果您的某个端点是一般规则的例外,我可以通过覆盖requestWithMethod:path:parameters:
来执行此操作:
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters {
request = [super requestWithMethod:method path:path parameters:parameters];
if (/* the endpoint specified in path returns XML */) {
[request setValue:@"text/xml" forHTTPHeaderField:@"Accept"];
} else {
[request setValue:@"text/json" forHTTPHeaderField:@"Accept"];
}
}
这是对tell, don't ask的轻微违反;在必要时随意重构。
如果您不打算升级到AFNetworking 2,那么您可以在这里停止阅读。
AFNetworking 2.0版使这更简单,更直观。在2.0中,序列化责任分为一个单独的类。此类的实例称为响应序列化程序。升级时,您需要一个AFCompoundResponseSerializer。文档最好地描述了它:
AFCompoundSerializer
是AFHTTPSerializer
的子类,它将响应序列化委派给返回AFHTTPSerializer
到YES
的第一个validateResponse:data:error:
对象,并返回默认值AFHTTPSerializer
的行为。这对于使用单个序列化程序支持多种潜在类型和结构的服务器响应非常有用。
例如:
AFJSONResponseSerializer *jsonSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:0];
AFXMLDocumentSerializer *xmlSerializer = [AFXMLDocumentSerializer serializerWithXMLDocumentOptions:0];
AFCompoundResponseSerializer *compoundSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:@[jsonSerializer, xmlSerializer]];
[AFHTTPSessionManager manager].responseSerializer = compoundSerializer;