iPhone:UI blocked when downloading data using NSURLConnection - iphone

I am using the NSURLConnection to download a video file from the server, at the same time playing the video by passing different url link to the movieplayer.
The problem is some blocking of the UI. During downloading we are unable to interact with the UI, like player zoom, pause button are blocked.
Code is like this for connection:_
connection1=[[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]] delegate:self];
in same mithod we are calling the
[playerInstance Play]
Please can you explain me where the problem is.

I can't understand your problem exactly. But I think you doing the two works (downloadig, playing file) on a same thread, probably main thread. So this may happen. So try to run the two processes in a separate threads.
[self performSelectorOnMainThread:#selector(playfile:) withObject:nil waitUntilDone:NO];
[self performSelectorInBackground:#selector(downloadfile:) withObject:nil];

You should make function for NSUrl operation and if it is already made call this function in following way for asynchronous communication.
[self performSelector:#selector(method) withObject:nil afterDelay:1];

Related

How to use NSOperationQueue to download audio files from server one by one

I have an array containing audio file url's. I want to fetch audio files from server using these url's in background mode. I have heard that i can achieve this with NSOperationQueue. My query is
1)How can i achieve this.
2)How can i get call back on single operation completion/failure
3)How can i get call back after completion of the whole process.
I need these call backs to keep track of downlaod process so that i can update my database about the download status of files. So, in case any internet connection loss i can download the remaning files again.
Any idea will be helpful as i am new to NSOperationQueue.
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(download:) object:aAudio];
[queue addOperation:operation];//added code
[operation release];
now do stuff what u want in method download. as per doc set [queue setMaxConcurrentOperationCount:1] for one by one.
Seems like AFNetworking has all that you need (callback blocks for success / failure, puttings requests in NSOperationQueue). In your case probably AFHttpClient and its enqueueHTTPRequestOperation method will do the job.

NSURLConnection threading problem

i have a big problem and i need your help. Here's what i need to accomplish:
The user select a row from a
TableView
A new view controller is pushed in
the NavigationController, and
displays only a "Loading" message
Meanwhile some data is read from an
XML file (via http)
When the data has been read, an
NSUConnection is used to load an
image from an URL (this URL is part
of the data)
While the image is still loading,
the other data is displayed on the
screen
The image has been downloaded and is
shown, completing the appearance of
the view
The big problem is that i can't use detachNewThreadSelector and NSURLConnection together!
So how can i make a workaround for this? How would you do this?
Thank you VERY much!
You can use following approach...(if you are using asynchronous request)
When your application comes in - (void)connectionDidFinishLoading:(NSURLConnection *)connection ... add a NSInvocationOperation object in NSOperationQueue (which you can handle at application level, by synthesizing it in appDelegate) ..
create NSInvocationOperation as follows..(in connectionDidFinishLoading)
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:#selector(parseIt) object:nil];
[appDelegate.operationQueue addOperation:operation];
[operation release];
-(void) parseIt
{
//ask for parsing stuff....what you have earlier wrote directly in connectionDidFinishLoading
}
Thanks,
I would use a NSTimer to solve the problem using detachNewThreadSelector and NSURLConnection together.
I have similar scenario where there is a downloading Progress UIViewController showing till the file getting complete, here is what i do:
I Draw a loading View contains a Activity Indicator for example.
I initialize a NSTimer to keep checking if the file is complete.
I call the method that contains the Download Logic.
[1]
-(void) vManageFileRequest
{
[self.oFilesManager vGetSingleFileRequest];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(vValidateFileRequest) userInfo:nil repeats:NO]];
}
[2]
[self performSelectorOnMainThread:#selector(vManageFileRequest) withObject:nil waitUntilDone:NO];

how to apply the backgroud process in my iPad application without effecting the process running on foreground?

I'm Developing an iPad application where I need to download file from the Webservice and I don't want it affect any other process running on the foreground.
I am displaying the data from the local database in my app and also this data is coming from the web service.
Help Is Appreciated.
Thank You Very Much in advance.
NSURLConnection and its delegate method will allow an asynchronous(background thread) load of a URL request.
Refer the NSURLConnection Class Reference
After getting the data from the server you should parse it on another secondary thread. Then you can save it to the Database.
You can find a better demonstration in the Apple sample apps. Please check the TopPaid app .
This sample app don't have a Database management module. But will teach you to develop a Universal (iPad and iPhone compatible app).
Few thoughts:
you can run the download process on separate thread.
Write a class as below
#interface FileDownloader : NSOperation
//with following methods:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:
[NSURLRequest requestWithURL:
[NSURL URLWithString:fileRecord.fileURLString]] delegate:self startImmediately:YES];
you can use thread use below method to detach thread
[NSThread detachNewThreadSelector:#selector(yourMethod) toTarget:self withObject:nil];
now perform your task in method
-(void) yourMethod {
//ur work
}
good luck
When downloading from a service in the background, I prefer to use synchronous calls running on a separate thread. This is how I do it in most of my apps.
call my generic method that spins a new thread
[[MyServiceSingleton sharedInstance] doSomeWorkInBackground:param1];
within singleton - define private method - doSomeWorkBackgroundJob (I use the empty category approach) to call within doSomeWorkInBackground method
[self performSelectorInBackground:#selector(doSomeWorkBackgroundJob:) withObject:param1];
within background job - create pool, do work, drain pool
- (void)doSomeWorkBackgroundJob:(NSString *)param1 {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
assert(pool != nil);
// you can call another method here or just create your synchronous request and handle the response data
[pool drain];
}

skpsmtpmessage in different thread

I have just successfully implemented skpsmtpmessage into my iPhone app. This works fine, but it runs on the main thread, causing the UI to lock up until the operation is complete. Therefore I have tried moving it to a second thread:
[NSThread detachNewThreadSelector:#selector(launchJobWithJob:) toTarget:self withObject:jobDescription];
If I do this that way, the class seems to get stuck on the connecting right away, with the only NSLog output being:
C: Attempting to connect to server at: mail.example.com:25
If I launch the job just by going [self launchJobWithJob:jobDescription];, it works fine but as I said before, lags heavily.
How can I get this to work in a background thread? Has someone come across this?
Edit: I have tried NSOperationQueue as well - the same happens again, just the log output and nothing else!
NSOperationQueue*queue = [NSOperationQueue new];
NSInvocationOperation*operation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(launchJobWithJob:) object:jobDescription];
[queue addOperation:operation];
[operation release];
I'm sure that it does its network connection stuff on the runloop, so let the runloop of the thread run until the operation is finished.
[[NSRunLoop currentRunLoop] run];
Must have some race condition, you can put some NSLog at you launchJobWithJob method to detect which code cause problem.

implementing UIActivityIndicatorView while NSData dataWithContentsOfURL is downloading

I am downloading an mp3 using NSData dataWithContentsOfURL:url. This takes a while and while the file is downloading the application hangs. I want to handle well and ideal would like to show the download progress but can't find methods for this.
It is in a UIViewController and I have made a first attempt by putting in a UIActivityIndicatorView and start it spinning before I start the download, then stop it spinning after but nothing appears.
So my question really is please could someone tell me what the best way to handle this is? Thanks so much
Nothing will appear because your main thread is blocked doing the download, and the main thread is where UI updates occur.
You should use NSUrlConnection to download asynchronously and implement the delegate methods to start/stop your spinner.
Alternatively if you want to stick with NSData's dataWithContentsOfURL:url you should do this on a separate thread and update the spinner on the main thread before and after you call it.
You can achieve this while still using synchronous methods, but you need to give the run loop a chance to start animating the activity indicator before you start the download.
You can achieve this by using either performSelector:withObject:afterDelay: with delay 0 to put a run loop between your animation start and the download, or (worse style, more risky) you can directly invoke the run loop within your code.
Sample code:
- (void)loadPart1 {
activityIndicator = [[[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIA...StyleGray]
autorelease];
activityIndicator.frame = myFrame;
[self.view addSubview:activityIndicator];
[activityIndicator startAnimating];
[self performSelector:#selector(loadPart2) withObject:nil afterDelay:0];
}
- (void)loadPart2 {
[NSURLConnection sendSynchronousRequest:request returningResponse:&response
error:&error];
[activityIndicator stopAnimating];
}
More details here:
http://bynomial.com/blog/?p=15
(scroll down to Solution 1 or Solution 2).