Libor Zapletal
Libor Zapletal

Reputation: 14102

iOS - multiple http requests - do something after all is fetched

I am using RestKit and I have following method. I have multiple requests in it and now I am thinking what is best approach (pattern maybe) to do something (for example hide loading alert) after all requests are done. I can set some global boolean values and in every request after it's done change it's own boolean value and check others if are done and then do something. But I am looking for some better solution. Are there some better way?

- (void)loadTypes
{
    RKObjectManager *restManager = [RKObjectManager sharedManager];
    [restManager getObjectsAtPath:@"remarkGetCategories"
                       parameters:nil
                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
     {
         NSArray* statuses = [mappingResult array];
         GetTypesResponse *response = [statuses firstObject];
         categoryArray = response.Data;
         [_tableView reloadData];
     }
                          failure:^(RKObjectRequestOperation *operation, NSError *error)
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                         message:[error localizedDescription]
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
         [alert show];

         NSLog(@"Hit error: %@", error);
     }];

    [restManager getObjectsAtPath:@"remarkGetTypes"
                       parameters:nil
                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
     {
         NSArray* statuses = [mappingResult array];
         GetTypesResponse *response = [statuses firstObject];
         typeArray = response.Data;
         [_tableView reloadData];

     }
                          failure:^(RKObjectRequestOperation *operation, NSError *error)
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                         message:[error localizedDescription]
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
         [alert show];
         NSLog(@"Hit error: %@", error);
     }];

    [restManager getObjectsAtPath:@"remarkGetSubTypes"
                       parameters:nil
                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
     {
         NSArray* statuses = [mappingResult array];
         GetTypesResponse *response = [statuses firstObject];
         subtypeArray = response.Data;
         [_tableView reloadData];

     }
                          failure:^(RKObjectRequestOperation *operation, NSError *error)
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                         message:[error localizedDescription]
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
         [alert show];
         NSLog(@"Hit error: %@", error);
     }];

    [restManager getObjectsAtPath:@"transactionAccounts"
                       parameters:nil
                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
     {
         NSArray* statuses = [mappingResult array];
         GetTypesResponse *response = [statuses firstObject];
         NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
         for (id object in response.Data) {
             BankAccount *bankAccount = [[BankAccount alloc] init];
             [bankAccount setValuesForKeysWithDictionary:object];
             [mutableArray addObject:bankAccount];
         }
         accountArray = [NSArray arrayWithArray:mutableArray];
         [_tableView reloadData];

     }
                          failure:^(RKObjectRequestOperation *operation, NSError *error)
     {
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                         message:[error localizedDescription]
                                                        delegate:nil
                                               cancelButtonTitle:@"OK"
                                               otherButtonTitles:nil];
         [alert show];
         NSLog(@"Hit error: %@", error);
     }];
}

Edit: Using ReactiveCocoa (RAC) for first method (remarkGetCategories). This is my helper class for RAC: @implementation ReactiveCocoaHelper

+ (RACSignal *)signalGetCategories {
    return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
        RKObjectManager *restManager = [RKObjectManager sharedManager];
        [restManager getObjectsAtPath:@"remarkGetCategories"
                           parameters:nil
                              success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
         {
             [subscriber sendNext:mappingResult];
             [subscriber sendCompleted];
         }
                              failure:^(RKObjectRequestOperation *operation, NSError *error)
         {
             [subscriber sendError:error];
         }];
        return nil; // `nil` means there's no way to cancel.
    }];
}

@end

This is my code for loading data:

RACSignal *signalCategories = [ReactiveCocoaHelper signalGetCategories];
[[RACSignal
  merge:@[ signalCategories ]]
 subscribeCompleted:^{
     NSLog(@"They're both done!");
     [_HUD hide:YES];
 }];

It's okay and I guess it would be working the way I want when I implement for all methods but for now I am not sure where and how to map result from request to my categoryArray.

Upvotes: 0

Views: 162

Answers (2)

Wain
Wain

Reputation: 119031

From a RestKit point of view, the restManager has an operationQueue parameter. So, in the success block you can check the operationCount to determine if all of the download and mapping operations are complete.

Upvotes: 1

Rickye
Rickye

Reputation: 1021

Check out ReactiveCocoa, it has an example especially for cases like this, it's the 6th code chunk in the Introduction section. It may seem complicated first, but it worth the effort of taking the time, it can seriously improve productivity, simplicity and stability.

Upvotes: 1

Related Questions