afnetworking httpclient子类带XMLPARSER
-
26-10-2019 - |
题
我正在编写一个小型iOS应用程序,该应用程序查询XML REST Web服务。使用的网络框架是 afnetworking.
情况
要查询Web服务,我将AFHTTPClient分类为:
@interface MyApiClient : AFHTTPClient
在实施中,我将其作为单身人士提供:
+ (MyApiClient *)sharedClient {
static MySharedClient *_sharedClient = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedClient = [[self alloc] initWithBaseUrl:[NSUrl URLWithString:@"http://url.to.the.webservice"]];
});
return self;
}
在initwithbaseurl中,我告诉afnetworking期望XML内容:
[self registerHTTPOperationClass:[AFXMLRequestOperation class]];
现在,我可以从我的ViewController上调用Singleton上的GetPatch,并且在成功块中开始解析我的返回的XML。在ViewController中的NSXMLPARSERDELEGATE方法中,我可以选择我感兴趣的XML部分并使用它做事。
问题
我想在我的httpclient Singleton中使用方法,该方法处理与Web服务并返回数据模型或模型列表而不是XML的所有内容。
例如,我想做这样的事情:
ServerModel *status = [[MyApiClient sharedClient] getServerStatus];
然后,ApicLient将在内部调用Web服务,解析XML并返回模型。我怎样才能做到这一点?通常,我会使用XML解析后会被调用的代表,但是由于apiclient的单身性质,可能会有多个代表吗?
希望有人能阐明这一点,谢谢!
解决方案
(为这个“有点”的答案表示歉意,但我们正在努力寻求更好的解决方案...)
您需要退后一步,仔细考虑设计。
您遇到问题,因为您有一个想法,即设计中的某些东西必须是单身人士,但是要么:
1) 这实际上不是必需的
2) 可能已经存在为您完成该工作的某些东西(例如,您正在使用的HTTP lib),
或者
3) 您正在将错误的事情变成单身人士,或者您还没有将设计分配到适当的部分以与Singleton Idea合作良好
那么,您能明确告诉我为什么要采用单身方法吗?只是为了确保一次只能发生一个网络请求吗?您的单例对象中是否有任何状态概念?然后,我将更新此答案或评论,等等。
(离题: 我还要补充说,在某些情况下,可能确实需要强的'singleton-我的意思是,确实只有一个可能的实例,就像您一样,该机制就被烘烤到您的对象中 - 但这不是。替代方案是虚弱的'Singleton,我的意思是您实际上做的核心对象具有平淡的 init
像往常一样的方法,但是共享对公共对象的访问通过另一个对象,这是一种简单的“工厂”,可以实例化/包含共享实例。这个弱的Singleton想法的优点是,您的代码在不同的上下文中更可重复使用 - 例如,您可以决定在以后同时同时执行多个HTTP请求/会话 - 有时会使写作测试的问题降低)。
其他提示
使用块而不是委托。
从我的Apiclient课程中:
- (void)getPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(id response))success
failure:(void (^)(NSError *error))failure
{
NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];
[self enqueueHTTPOperationWithRequest:request success:success failure:failure];
}
-(void)fetchAllUsersSuccess:(void (^)(id))success
failure:(void (^)(NSError *))failure
{
[self getPath:@"/api/mobile/user/"
parameters:nil
success:^(id response) {
if([response isKindOfClass:[NSXMLParser class]]){
//parse here to new dict
success(newDict);
} else
success(response);
} failure:^(NSError *error) {
failure(error);
}];
}
现在我可以使用它:
ServiceApiClient *apiClient = [ServiceApiClient sharedClient];
[apiClient fetchAllUsersSuccess:^(id dict) {
for (NSDictionary *object in [dict objectForKey:@"objects"]) {
[ServiceUser addUserFromDictionary:object
inContext:self.managedObjectContext];
}
NSError *error= nil;
[self.managedObjectContext save:&error];
if (error) {
NSLog(@"%@", error);
}
} failure:^(NSError * error) {
NSLog(@"%@", error);
}];