Reputation: 3588
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
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
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
Reputation: 107131
There are a lot of ways:
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
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
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