Ensuring non-expired token before every request I'm developing an iOS application where data is fetched from a third-party REST API. Each request must contain an authorization token.

In order to implement this, I've written a fetchToken withCompletionBlock:(void (^)(ASToken*) token,NSError * error) method in AppDelegate:

-(void) fetchTokenWithCompletionBlock:(void (^)(ASToken * token, NSError * error)) completionBlock
{
    if (!_token) {
        _token = [self retrieveTokenFromKeychain];
    }

    if (!_token || _token.isExpired) {
        [ASMyApi loadTokenWithcompletionBlock:^(ASToken *token, NSError*  error) {

            if (token) {
                _token = token;
                [self saveTokenToKeychain: token];
            }else{
                completionBlock(nil,&amp;error);
            }

        }];
    }else{
        completionBlock(_token,nil);
    }
}


Before every requests that requires Authorization, fetchToken withCompletionBlock:(void (^)(ASToken*) token,NSError ** error) is called to retrieve the token. Here's an example:


-(IBAction) loadCategories
{
    [self.refreshControl beginRefreshing];
    [((AppDelegate *)[UIApplication sharedApplication].delegate) fetchTokenWithCompletionBlock:^(ASToken *token, NSError *error) {

        if (token) {
            [ASMyApi loadCategories:token.token completionBlock:^(NSArray *categories, NSError *error) {

                [self.refreshControl endRefreshing];

                if (categories){

                    self.categories = categories;

                }else{

                    [self monitorNetworkReachability];

                }

                [self updateUI];

            }];

        }else{

            [self.refreshControl endRefreshing];
            [self monitorNetworkReachability];
        }

    }];
}



I'm not happy with this code for the following reasons:


The nested nature of the callbacks makes it look ugly and somewhat unreadable
Too much repetition: The code to get the token is verbose and must be called before each request. The failure code is also repeated.


What I do like about this approach is that it ensures that there's always a valid token before sending the request (as opposed to having the request fail, and then requesting a new token).

I'd appreciate a second-opinion on this design and input on how it might be refactored.
You could introduce a delegate instead passing another block in loadCategories method. 

First, the protocol:

@protocol ASMyApiCategoriesDelegate &lt;NSObject&gt;

    @required
    - (void) ASMyApiCategoriesDidLoad:(NSArray *)categories;
    - (void) ASMyApiCategoriesDidFailToLoadWithError:(NSError *)error

@end


You change the signature of + [ASMyApi loadCategories:completionBlock:] to accept a delegate:

+ (void) loadCategoriesToken:(id)token delegate:(id &lt;ASMyApiCategoriesDelegate&gt;)delegate
{
    NSArray *categories;
    // code that loads categories

    if (categories)
    {
        [delegate ASMyApiCategoriesDidLoad:categories];
    }
    else
    {
        [delegate ASMyApiCategoriesDidFailToLoadWithError:nil];
    }
}


In your view controller you'll have to implement the required methods from ASMyApiCategoriesDelegate protocol and update loadCategories method.

- (void) ASMyApiCategoriesDelegateDidLoad:(NSArray *)categories
{
    [self.refreshControl endRefreshing];
    self.categories = categories;
    [self updateUI];
}

- (void) ASMyApiCategoriesDelegateDidFailToLoadWithError:(NSError *)error
{
    [self.refreshControl endRefreshing];
    [self monitorNetworkReachability];
}

- (IBAction) loadCategories
{
    [self.refreshControl beginRefreshing];
    [((AppDelegate *)[UIApplication sharedApplication].delegate) fetchTokenWithCompletionBlock:^(ASToken *token, NSError *error) {
        if (token)
        {
            [ASMyApi loadCategories:token.token delegate:self];
        }
        else
        {
            [self ASMyApiCategoriesDidFailToLoadWithError:nil];
        }
    }];
}