我正在编写一个小型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);
}];
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top