What is BEST way to download data from server and show in UITableViewController or UIViewController without stuck of its GUI?

StackOverflow https://stackoverflow.com/questions/19002859

سؤال

There are many structures to download data from server. like

  1. ViewDidLoad Make NSURLConnection, call its delegate and when connection ends, make parser and parser data and then save to DB. (EVERYTHING IN THE SAME CLASS)

Another way is

  1. Make a separate class, that will manage all NSURLConnections + NSXMLParser, and just make object of that class in ViewDidLoad or any other method of ViewController Class.

Another way is

  1. Make a file to set connection, and make another file to manage parser

     ViewController =====================>> URLConnection
     Delegate of URLConnectionfile =====================>> ViewController 
    

then, in this delegate, NSData which is downloaded from server is further send to Parser class

   ViewController =======================>> ParserClass
  Delegate of Parser gives Array to ================= ViewController

then display that Array

Another way is to use thread

  1. Call such methods in

    [self performSelectorInBackground:@selector(doSomething) withObject:nil];

then in doSomething , call your connection file

Can anyone define the best way to download and save in a very organised and proper way, so that it becomes easy to manage and no hang of View occur.

هل كانت مفيدة؟

المحلول

Don't operate your downloading and parsing code on main thread. That is the only way to avoid UI freezes.

Recommended ways,

  1. NSOperation and NSOperationQueue
  2. GCD
  3. Use 3rd party frameworks like AFNetworking, MKNetworkKit etc.

Also, if you have images in your table view, use technique called lazy loading.

I'd recommend not to use [self performSelectorInBackground:@selector(doSomething) withObject:nil];. It gets messy if you don't know how to use, rather use GCD.


EDIT

Usually, what I follow,

  • Webservice engine class which handles web service calls with NSOperation and NSOperationQueue (you can use GCD or other framework). Any view controller making call to the WS will talk to this class.
  • Parser class will receive WS response from Webservice engine. It will parse response and create model class. On completion it will delegate parsed response to Webservice engine and from here it will be delegated to view controller.
  • Error handling and progress indication is handled in Webservice engine.
  • Important: Point where request is made from the view controller, the processing happens on background thread created by NSOperationQueue. Thus not freezing the UI.

Call to WS is initiated in viewDidLoad, with progress indicator shown until process completes. But some times requirement is that the view controller is not created until WS response is downloaded. So choice to initiate request is based on your requirement.

نصائح أخرى

From iOS4+ Apple have introduced GCD. See Concurrency Programming Guide: Dispatch Queues

This is probably the best and most recommended way of doing the async stuff(especially webcalls).

Example

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    NSData *responseData = nil;

    NSDictionary *responseDictionary = nil;
    responseData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60] returningResponse:&response error:&error];

    //Update the UI after this
    dispatch_async(dispatch_get_main_queue(), ^{
        [self updateUIAfterParsing]; 
    });

});

My suggestion is, you can go with GrandCentralDispatch(GCD)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        for(NSString *urlString in self.urlArray)
        {
            NSURL *url=[NSURL URLWithString:urlString];
            NSData *data=[NSData dataWithContentsOfURL:url];

            UIImage *image=[UIImage imageWithData:data];

           //delegate to parse the content/data  
           //delegate to save data/images into documents directory/DB 


         }

            dispatch_async(dispatch_get_main_queue(), ^{

                //UIUpdation, fetch the image/data from DB  and update into your UI
            });




    });
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top