1

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.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Duaan
  • 609
  • 1
  • 13
  • 29
  • To be honest, you very likely don't get a "BEST way" answer - since this would require a rather sophisticated solution, which opens half a dozens other sub-problems, each worth a separate SO question. What you likely get as answers though, are "quick" solutions with lots of caveats, which work only under mild conditions. – CouchDeveloper Sep 25 '13 at 14:29

3 Answers3

1

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.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Amar
  • 13,202
  • 7
  • 53
  • 71
  • Amar where to user GCD, I means in which class, can you define a bit more, like ViewDidLoad and then calling this method or giving URL and where to call NSXMLParser??????\ – Duaan Sep 25 '13 at 11:19
  • This is clear to me, now can you give me ONE Method body of Webservice engine which downloads NSData and give it to Parser ????? I simply want to see how you have created the NSOperation and NSOperationQueue there. Thanks alot. – Duaan Sep 25 '13 at 11:39
  • 1
    Create an `NSOperation` subclass. It will simply have a `NSURLConnection` doing downloads. The same operation can initiate call to parser. The Webservice engine class(singleton) contains various methods for number of WS calls along with the delegate. Each WS call will create operation instance and add it to the queue, which is to be create once in Webservice engine. Code is as straightforward as I explained the steps. It should not be difficult if you try out. – Amar Sep 25 '13 at 11:46
  • If I have 5 request, so should I make 5 methods in Webservice Engine or should I make separate Engines (5 CLASSES) for each request???? – Duaan Sep 25 '13 at 11:47
  • I liked your comment Sir, its almost clear to me, but if you would provide us .h and .m or webservice engine, or any one method of it, it will be easy, as I have never used NSOperation and such operations before. Thanks in Advance. – Duaan Sep 25 '13 at 11:50
1

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]; 
    });

});
Xcoder
  • 1,762
  • 13
  • 17
  • and where this dispatch code will be written and what are contents of updateUIAfterParsing? – Duaan Sep 25 '13 at 11:18
  • enclose it within a method and call this from viewDidLoad. updateUIAfterParsing is what you do with the data. – Xcoder Sep 25 '13 at 11:53
0

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
            });




    });
wesley
  • 859
  • 5
  • 15