具有多个快速连续请求的AFHTTPSessionManager(AFNetworking 2.0)

时间:2014-02-24 11:40:28

标签: ios objective-c networking afnetworking-2

我是iOS编程新手,还在学习。

编辑:!!!!!!我的代码中的所有内容都有效。我的问题是关于我使用的委托模式, 如果我在背景中产生我不知道的问题,或者是否有更好的方法来处理我在AFNetworking中的情况......

我通过继承AFHTTPSessionManager为我的应用创建了一个API。 我的API创建一个单例并返回它并为各种请求提供公共函数。这些函数创建参数列表,并在服务器上发出GET请求,如下所示:

- (void)getCharacterListForKeyID:(NSString *)keyID vCode:(NSString *)vCode sender:(id)delegate
{
    NSMutableDictionary *parameters = [NSMutableDictionary dictionary];

    parameters[@"keyID"] = keyID;
    parameters[@"vCode"] = vCode;

    [self GET:@"account/Characters.xml.aspx" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {

        self.xmlWholeData = [NSMutableDictionary dictionary];
        self.errorDictionary = [NSMutableDictionary dictionary];
        NSXMLParser *XMLParser = (NSXMLParser *)responseObject;
        [XMLParser setShouldProcessNamespaces:YES];
        XMLParser.delegate = self;
        [XMLParser parse];

        if ([delegate respondsToSelector:@selector(EVEAPIHTTPClient:didHTTPRequestWithResult:)]) {
            [delegate EVEAPIHTTPClient:self didHTTPRequestWithResult:self.xmlWholeData];
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if ([delegate respondsToSelector:@selector(EVEAPIHTTPClient:didFailWithError:)]) {
            [delegate EVEAPIHTTPClient:self didFailWithError:error];
        }
    }];
}

我之前使用的是普通协议/委托方法。但是,一旦我像这样不止一次地调用这个API :(它就像这样:)

EVEAPIHTTPClient *client = [EVEAPIHTTPClient sharedEVEAPIHTTPClient];
client.delegate = self;
[client getCharacterListForKeyID:self.keyID vCode:self.vCode];

以前的呼叫被委托被覆盖了。所以我改变了以上的风格。将发送者作为参数传递给函数:

EVEAPIHTTPClient *client = [EVEAPIHTTPClient sharedEVEAPIHTTPClient];
[client getCharacterListForKeyID:self.keyID vCode:self.vCode sender:self];

我将此发件人传递给GET请求的成功和失败块。

我想知道的是:“这是一个很好的编程习惯吗?”如果可能的话,应该避免将对象传递给这样的块?在AFHTTPSessionManager中是否还有其他更优雅的方法来处理这种类型的工作(使用不同的参数反复进行相同的GET请求并将结果返回给相应的请求所有者)更优雅?

1 个答案:

答案 0 :(得分:2)

当涉及简单性和异步请求处理时,委托模式就会动摇。你应该使用块,这是一个例子

您的服务器类:

static NSString *const kNews = @"user_news/"; // somewhere above the @implementation

- (NSURLSessionDataTask *)newsWithPage:(NSNumber *)page
                            lastNewsID:(NSNumber *)lastNewsID
                            completion:(void (^)(NSString *errMsg, NSArray *news, NSNumber *nextPage))completionBlock {
  return [self GET:kNews
        parameters:@{@"page" : page,
                     @"news_id" : lastNewsID
                     }
           success:^(NSURLSessionDataTask *task, id responseObject) {
             NSArray *news = nil;
             NSNumber *nextPage = nil;
             NSString *errors = [self errors:responseObject[@"errors"]]; // process errors

             if ([responseObject[@"status"] boolValue]) {
               news = responseObject[@"news"];
               nextPage = responseObject[@"next_page"];
               [self assignToken];
             }

             completionBlock(errors, news, nextPage);
           }
           failure:^(NSURLSessionDataTask *task, NSError *error) {
             NSString *errors = [self errors:error];
             completionBlock(errors, nil, nil);
           }];
}

来电者

- (void)dealloc {
  [_task cancel]; // you don't want this task to execute if user suddenly removes your controller from the navigation controller's stack
}

- (void)requestNews {
  typeof(self) __weak wself = self; // to avoid the retain cycle
  self.task = [[GSGServer sharedInstance] newsWithPage:self.page
                                            lastNewsID:self.lastNewsID
                                            completion:^(NSString *errMsg, NSArray *news, NSNumber *nextPage) {
                                                 if (errMsg) {
                                                   [GSGAppDelegate alertQuick:errMsg]; // shortcut for posting UIAlertView, uses errMsg for message and "Error" as a title
                                                   return;
                                                 }
                                                 [wself.news addObjectsFromArray:news];
                                                 wself.lastNewsID = [wself.news firstObject][@"id"];
                                                 wself.page = nextPage;
                                                 [wself.tableView reloadData];
                                               }];
}