Anupam Mishra
Anupam Mishra

Reputation: 3588

How to run a thread in background of application which will not affect my application user interface

I have made an application for IOS, in which I am using sqlite database, database is local in application. Now I have given the functionality the application is downloading data from internet & put it in local database & show infront of user. I have given this functionality on - (void)viewDidLoad so that when application is downloading data, it stop working till it finish downloading part, for this user need to wait to interact with application.

Now I wants to functionality a thread run in background of application which will connect the internet & update the application without interfering user. please help me.

My code of download & save image is this:

 -(void)Download_save_images:(NSString *)imagesURLPath :(NSString *)image_name   
   {                              

      NSMutableString *theString = [NSMutableString string];

    // Get an image from the URL below    
      UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:NSURL  URLWithString:imagesURLPath]]];        
      NSLog(@"%f,%f",image.size.width,image.size.height);        
     NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    // If you go to the folder below, you will find those pictures
     NSLog(@"%@",docDir);    
    [theString appendString:@"%@/"];
    [theString appendString:image_name];
    NSLog(@"%@",theString);
    NSLog(@"saving png");
    NSString *pngFilePath = [NSString stringWithFormat:theString,docDir];
    NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
    [data1 writeToFile:pngFilePath atomically:YES];  

    NSLog(@"saving image done");

    [image release];
   // [theString release];
}

when i am debugging application i seen my application taking more time at below line:

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:NSURL  URLWithString:imagesURLPath]]];

Upvotes: 2

Views: 1657

Answers (5)

Mev
Mev

Reputation: 1625

Questions like these were asked hundreds of times before. I suggest you do a quick search on this. Also there is a topic in apple documentation covering this area thoroughly. here

Basically you can do this with operation queues or dispatch queues. There are some code snippets given above by Avi & Amar.

I'd like to add something since you seem to be unfamiliar with the topic & you mentioned there are web requesting involved.

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    // Dont DIRECTLY request your NSURL Connection in this part because it will never return data to the delegate...
//  Remember your network requests like NSURLConnections must be invoked in mainqueue
// So what ever method you're invoking for NSURLConnection it should be on the main queue

        dispatch_async(dispatch_get_main_queue(), ^{
                // this will run in main thread. update your UI here.
        });
    });

I've given small example below. you can generalise the idea to match your needs.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        // Do your background work here

        // Your network request must be on main queue. this can be raw code like this or method. which ever it is same scenario. 
        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];
        dispatch_async(dispatch_get_main_queue(), ^{

            [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse *res, NSData *dat, NSError *err)
             {
                 // procress data

                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

                     // back ground work after network data received

                     dispatch_async(dispatch_get_main_queue(), ^{

                         // finally update UI
                     });
                 });
             }];
        });
    });

Upvotes: 1

Shahzin KS
Shahzin KS

Reputation: 1001

You can also use NSOperationQueue and NSBlockOperation if you find GCD difficult.

NSBlockOperation *operation=[[NSBlockOperation alloc] init];

[operation addExecutionBlock:^{
    //Your code goes here

}];

NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[queue addOperation:operation];

In GCD You could achieve the same using

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
   //Your Code to download goes here

    dispatch_async(dispatch_get_main_queue(), ^{
       //your code to update UI if any goes here

    });
});

Use either of the API Depending upon your needs. Check this thread which discuss about NSOperationQueue vs GCD for more info.

Upvotes: 3

Midhun MP
Midhun MP

Reputation: 107131

There are a lot of ways:

1 . Grand Central Dispatch

dispatch_async(dispatch_get_global_queue(0, 0), ^{
  //Your code
});

2 . NSThread

[NSThread detachNewThreadSelector:@selector(yourMethod:) toTarget:self withObject:parameterArray];

3 . NSObject - performSelectorInBackground

[self performSelectorInBackground:@selector(yourMethod:) withObject:parameterArray];

Upvotes: 0

amar
amar

Reputation: 4345

Use GCD

create your dispatch object

dispatch_queue_t yourDispatch;
yourDispatch=dispatch_queue_create("makeSlideFast",nil);

then use it

dispatch_async(yourDispatch,^{
//your code here

//use this to make uichanges on main thread
dispatch_async(dispatch_get_main_queue(), ^(void) {
});


});

Do ui on main thread only by using

dispatch_async(dispatch_get_main_queue(), ^(void) {
});

Then release it

dispatch_release(yourDispatch);

Here is tutorial

Upvotes: 0

Avi Tsadok
Avi Tsadok

Reputation: 1843

You can us GCD, like that:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // put here your background code. This will run in background thread.

    dispatch_async(dispatch_get_main_queue(), ^{
            // this will run in main thread. update your UI here.
    });
})

But you need to understand how blocks work for example. Try it.

Upvotes: 0

Related Questions