简体   繁体   中英

how to manage concurrently two AFNetworking operations from two different controllers

I am running two AFJSONRequestOperation from two view controllers, they gets called one right after the other:

viewcontroller1:

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){

//
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response,NSError *error, id JSON){
//
}];
[operation start];
[SVProgressHUD showWithStatus:@"Searching for products, please wait.."];

viewcontroller2:

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){

//
}failure:^(NSURLRequest *request, NSHTTPURLResponse *response,NSError *error, id JSON){
//
}];
[operation start];
[SVProgressHUD showWithStatus:@"Loading categories.."];

The problem is that the status shown is only for the second operation: Loading categories.. although they completed both networking and getting JSON results just fine.

It seems I cannot use NSOperationQueue since the two operations are in separated controllers. So how to make sure one wait until the first is done to show both status messages to user?

A couple of thoughts:

  1. You certainly could use the same operation queue for the two operations if you really wanted. You'd either pass the operation queue from the first controller to the second one. Or you could have a singleton class for your queue.

  2. That's a moot point, though, because you can also establish a dependency of the second operation upon the completion of the first operation without using a shared queue. You'd just need to pass the NSOperation for the first request from the first controller to the second one, and then you set that first operation to be a dependency for the second one.

  3. That, too, is a moot point, though, because why would you want to introduce an artificial constraint of serial operation if you don't have to. Two network operations can run considerably faster if you run them concurrently rather than sequentially. It seems like a shame to punish the user with slower performance for the sake of simplifying your effort to update the HUD.

  4. The right solution, in my opinion, would be to support concurrent operations and update the HUD appropriately. Perhaps maintain a mutable array of status messages that you can add and remove from the list.

Perhaps something like:

@interface HUDStatus ()
@property (nonatomic, strong) NSMutableArray *statusMessages;
@end

@implementation HUDStatus

+ (instancetype)sharedHudManager
{
    static id sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (id)init
{
    self = [super init];
    if (self) {
        _statusMessages = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)addMessage:(NSString *)message
{
    [self.statusMessages addObject:message];
    [SVProgressHUD showWithStatus:message];
}

- (void)removeMessage:(NSString *)message
{
    __block BOOL didFindMessage = NO;

    // remove the message (not sure which one it is, so we'll look through all of them

    [self.statusMessages enumerateObjectsWithOptions:0 usingBlock:^(NSString *oldMessage, NSUInteger idx, BOOL *stop) {
        if ([oldMessage isEqualToString:message])
        {
            [self.statusMessages removeObjectAtIndex:idx];
            didFindMessage = YES;
            *stop = YES;
        }
    }];

    if (!didFindMessage)
        NSLog(@"%s: Trying to remove '%@' but it was not found in %@", __FUNCTION__, message, self.statusMessages);

    // if, having removed
    if ([self.statusMessages count] > 0)
        [SVProgressHUD showWithStatus:[self.statusMessages lastObject]];
    else
        [SVProgressHUD dismiss];   // I don't know this class, so I don't know what the name of the method to dismiss the HUD
}

@end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM