Search code examples
iosobjective-cios7afnetworking

Objective-C: View displays empty Table since API takes time to fetch from Server


I have a TransactionViewController that during instantiation fetches data from API and looks like

- (id)init {
    self = [super init];
    if (self) {
        TransactionsModel *transactionsModel = [TransactionsAPI getTransactionsForYear:2014 AndMonth:9];
        self.transactionsModel = transactionsModel;
    }
    return self;

}

The API get data as following

+ (TransactionsModel *)getTransactionsForYear:(int)year AndMonth:(int)month {
    NSDictionary *transactions = [self getTransactions];
    NSLog(@"transactions: %@", transactions);
    return [[TransactionsModel alloc] initWithJson:transactions];
}

and

+ (NSDictionary *)getTransactions {
    AFHTTPRequestOperationManager *manager = [RestHelper getSecureManager];
    __block NSDictionary* transactions = nil;

    [manager GET:[appUrl stringByAppendingString:@"rest/transactions/2014/11"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

        transactions = responseObject;
    }    failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
    return transactions;
}

I am using AFNewtworking 2.0 in which every call is asynchronous, right?

Question How do I wait to display my Table until data is fetched from server?

P.S I am new to iOS programming and looking for recommended ways to solve these issues. Thanks


Solution

  • You would need to turn your complete code into an asynchronous implementation. See my example edit below.

    + (void)getTransactionsWithCompletionHandler:^(NSDictionary *responseObject)completionHandler {
        AFHTTPRequestOperationManager *manager = [RestHelper getSecureManager];
        [manager GET:[appUrl stringByAppendingString:@"rest/transactions/2014/11"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            completionHandler((NSDictionary *)responseObject);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
        }];
    }
    

    You would also need to call -reloadData in your block that you pass when using the method:

    - (id)init {
        self = [super init];
        if (self) {
            TransactionsModel *transactionsModel = [TransactionsAPI getTransactionsForYear:2014 AndMonth:9 completionHandler:^(NSDictionary *transactions) {
                self.transactionsModel = transactions;
                [self.tableView reloadData];
            }];
        }
    }
    

    And in your API:

    + (void)getTransactionsForYear:(int)year AndMonth:(int)month completionHandler:^(TransactionsModel *transactions)completionHandler {
        [self getTransactionsWithCompletionHandler:^(NSDictionary *transactions) {
            TransactionsModel *model = [[TransactionsModel alloc] initWithJson:transactions];
            completionHandler(model);
        }];
    }