If I have a large file download going on an the app gets moved to background, is there any way to keep the download executing functions alive?
I knowbeginBackgroundTaskWithExpirationHandler: gets called when the app moves to the background and I can start my task there, but I don't want to start a new task, I want to complete my old task. It can be solved with beginBackgroundTaskWithExpirationHandler:, but for that I need to pause my download and resume it from the right place, which is just plain silly.
Ideally what I want is that I wrap my download function with an expiration handler, so my download function keeps executing for the permitted time after the app has been moved to the background.
Ideally what I want is that I wrap my download function with an expiration handler, so my download function keeps executing for the permitted time after the app has been moved to the background.
This is exactly how it works. beginBackgroundTaskWithExpirationHandler: is not called when you enter the background. It's what you call to indicate that you're starting something that, if you happen to go into the background while it's running, you would like to finish. Just wrap your existing download code with beginBackgroundTaskWithExpirationHandler: and endBackgroundTask:.
It is perfectly fine to start a background thread when you're in the forground. Add your custom expiration handler. Do an asynchronous request.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
[self performYourStuffInTheBackGround];
});
And a quote from AppleDEV;
you will probably want to use asynchronous network APIs. iOS provides a wide variety of APIs to do this—from low-level APIs like GCD to high-level APIs like NSURLConnection, with many stops in between—and we encourage you to use them.
Related
I'm building a Windows Phone application that does video capture in a page and has a custom player in another page. I'm using my own custom codec so the player needs a lot of DispatcherTimer to keep track of several behaviors on the UI part and serve the movie at the good framerate in the codec part.
I'm trying to release all DispatcherTimer as I know they are CPU intensive, but even when stopping them my app is still very slow. If I press back-back then follow the flow, the speed divides by two each time. If I don't use my player, eveything is ok. And my player is only made of 3 DispatcherTimer, a FileStream and an Image box.
I feel that DispatcherTimer are still running in memory and are double-instantiated even if they are instantiated as private on the page directly.
Can I force the page to release all this stuff?
Actually I don't understand yet what is the difference between navigating to a page next to current page, or navigating back. I don't know i.e. how the page is shown again without calling InitializeComponents, so I'm mixed up about which resources to release, and which resources to keep intact.
My execution speed problem was really caused by some running DispatcherTimer, so I'll answer it to have it archived.
The solution:
Ensuring that all DispatcherTimer has been instantiated directly on the page so that we can nullify them from anywhere in the code.
In OnNavigatedFrom, I kill the DispatcherTimer and in OnNavigatedTo, I recreate them with myDispatcherX = new DispatcherTimer();
No "temporary" timers, like "DispatcherTimer myTempTimer = new DispatcherTimer; with ((DispatcherTimer)send).Stop() in callback, as chances are that it remains in memory in an application where we navigate.
I have an (old) audio app that is misbehaving on iOS 5.1.1. It records audio and on older iOS versions (don't know precisely where the "break" is) it would stay "in foreground" while recording, without any nudging.
But on 5.1.1 the app is put into background after two minutes, and then things go sour. Currently (will have to change this, I suppose) the app kills recording when it's backgrounded (and it appears to do this successfully), but it still dies with a trap in the above routine.
Unfortunately, the call stack is empty when this occurs, so there's little clue as to why the app's getting killed, but I gather (just from hints here and there on the web) that the trap occurs because a background app cannot use any UI facilities, and the app must somehow be calling something UI-ish. But I haven't a clue what it might be.
I've worked through most of the notifications, to see if a notification might be lurking in a queue somewhere and doing something, but I've not found anything so far that might be triggering a UI opp.
Any ideas on how to track this down?
Aha!! The app uses an Apple freebee widget known as AQLevelMeter. When recording is stopped, the level meter is also stopped, but the stop code inside AQLevelMeter.mm does not invalidate the timer that's driving the UI updates.
When a user first opens my app, I need to download and install some content from a server before they can begin using the app. The problem is that this takes around 5 minutes on wifi, during which time the app goes into the background and the download is suspended.
Is there any way to either:
prevent an iOS app from entering the background whilst I perform my download
or continue peforming the task in the background (i.e. perform the task irrespective of whether the app is in the foreground or background)
Thanks
It really doesn't matter, if the user presses the home button it will go to background. Although you can do two things to mitigate the problem:
Use beginBackgroundTaskWithExpirationHandler, to give you a bit more time to download. Which you can read here.
Don't allow the device to become iddle, with [UIApplication sharedApplication].idleTimerDisabled = YES;. You can read more about that here.
Either way, the best thing you can do is to tell the user, that is an important download and he shouldn't quit the application.
Can't you include some or all of the content in your app bundle instead, and just download changes on first run?
I can't imagine this is a good first user experience, and it may not pass App Store review like this.
The only third party apps that are allowed to download in the background are newsstand apps loading issue content, and Apple are pretty strict about what they allow as newsstand apps.
You can't do what you want, in this situation. One way, and I think the best and only, is to resume your download when you app becomes active (returns to foreground state). Also, don't forget to register for connectivity notifications (Reachability class can be used for this purpose from this Apple sample app http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html). Good Luck!
While launching the application in my iPhone, I need to download the data from the server. While downloading data(in middle of process) if I press home button to enter the application into background.this time I need to stop the API request which is already executing. currently applicationDidEnterBackground method is calling with delay(after downloading data). In the mean time application is crashing. how can we cancel the URL connection while application is entering to background.
Please help me out.
Thanks in advance.
One way to do it is to set some kind of flag in your app controller that you can periodically check to see if the request is cancelled.
Or, even better, the NSThread object provides a mechanism to indicate that it should be cancelled. If you go into the background, set your detached thread to cancel (via [NSThread cancel]) and then in whatever API callsback you have, you should periodically check to see if [NSThread isCancelled] is returning YES.
Here's a link to Apple's documentation on [NSThread cancel].
http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSThread_Class/Reference/Reference.html#//apple_ref/occ/instm/NSThread/cancel
hope this helps!
I want to register my app for push notification when my application terminates so i think if i delay my app quitting time it could be possible.Does someone knows how to delay application quitting time? I think this method
[self performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait];
will do my job but i don't know how to use this method if someone knows please tell.I need to send some data to a server along with registering for Push Notification when my app quits.
I can't imagine why you would want to do this. If it were even possible it would be extremely annoying for a user to tap the home button and the app to take x amount of time to shut down. This time 'x' being dependent on the server connection creates even more user headache.
Apple have the home button exit apps immediately for a reason.
If you want to register the Push Notifications like you suggest, do it while the app is running. If your worrying that they won't be properly set if the user exits prematurely... don't.
As users, we all know there are sometimes consequences of exiting a program without giving it time to save your settings.
For push notification it is better to register when the app first starts and then send the push token to your server in the background. However, if you have a good reason why you need to do the registration just as the app terminates, I believe you can do this if you are using iOS 4. iOS 4 has a new feature called "task finishing" that allows an app to stay running for a few minutes after the user closes it so that it may finish up any tasks it was in the middle of (such as saving data).