Search code examples
objective-cjsonmultithreadinguitableviewdispatch-async

which dispatch_async method is advisable to load the json data to table view controller?


I have json data and now I want to push into table view? But initially, I have to get the json data so which dispatch method or child thread is recommend so that i can load the data in background and then push it.


Solution

  • Best practice is load data in background thread using dispatch_async method and passing a queue other then main so it don't block UI, and when u have data ready just call reload table view on main thread... Below is a class an example from real project... Class level method load transcations

    + (void)getAllTransactionsWithHandler:(void(^)(NSArray *transactions, NSError *error))handler{
        dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(q, ^{
            NSURL *url = [[NSBundle mainBundle] URLForResource:trnasactionFileName withExtension:@"json"];//[NSData dataWithContentsOfFile:trnasactionFileName];
            NSData *data = [NSData dataWithContentsOfURL:url];
            if (!data) {
                if (handler) {
                    handler(nil, [NSError errorWithDomain:@"bank" code:900 userInfo:nil]);
                }
                return ;
            }
            NSError *error = nil;
            NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
            if (error) {
                if (handler) {
                    handler(nil, error);
                }
            }
            else{
                Transaction *transaction;
                NSString *dateString;
                NSMutableArray *objects = [NSMutableArray new];
                for (NSDictionary *dic in jsonArray) {
                    transaction = [Transaction new];
                     dateString = dic[kOccured];
                    NSDateFormatter *dateFormater = [NSDateFormatter new];
                    [dateFormater setDateFormat:@"yyyy-MM-dd"];
                    transaction.occured = [dateFormater dateFromString:dateString];
                    transaction.proecessed = [dateFormater dateFromString:dic[kProcessed]];
                    transaction.desc = dic[kDescription];
                    transaction.amount = dic[kAmount];
                    [objects addObject:transaction];
                }
                if (handler) {
                    handler([NSArray arrayWithArray:objects], nil);
                }
            }
    
        });
    }
    

    You can use this as

     [Transaction getAllTransactionsWithHandler:^(NSArray *transactions, NSError *error) {
            if (error) {
    
            }else{
                if ([transactions count] > 0) {
                    weakSelf.objects = transactions;
                    runOnMainThread(^{
                        [weakSelf.tableView reloadData];
                    });
    
    
                }
            }
        }];
    

    Where as runOnMainthread is a utility method which will run provided block of code on main thread

    void runOnMainThread(void(^block)(void)){
        if ([[NSThread currentThread] isMainThread])
            block();
        else{
            dispatch_sync(dispatch_get_main_queue(), ^{
                block();
            });
        }
    }