How to know if current device can have background mode - iphone

I am doing some tasks after having entered in background mode. I want to do these tasks only if I am in background mode so I did :
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
But applicationState is only available in iOS 4.0 and later...
I wonder how this piece of code will work on iOS 3 for example.
How can I know if the device has iOS 4 ?
How can I avoid crash and exceptions for iOS < 4 ?
Thansk for your help
Kheraud

You can check whether the current iOS supports returning the current application state by using -respondsToSelector:
if ([[UIApplication sharedApplication] respondsToSelector:#selector(applicationState)] ){
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
}
You can determine whether multitasking support is available (even devices running iOS 4 or later may not have the hardware to support multitasking) by specifically checking for background support:
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:#selector(isMultitaskingSupported)])
backgroundSupported = device.multitaskingSupported;
You can retrieve the iOS version by using the following code (although you should not really rely on the following code to infer background support):
float osVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
Finally, if you want to perform some tasks just after having entered background mode, you'll want to take advantage of the following event:
- (void)applicationDidEnterBackground:(UIApplication *)application
.. but note that your time will be very limited. You will have approximately five seconds to do whatever you want to do. In case you need more, you can try asking iOS for additional time:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
Note that in this case, you might be granted more time by iOS (or not), but it's still a finite-length time.
Apple's Executing Code in the Background is a worth read.

I discovered this link very usefull to understand how to handle both 3.1 and >4.0 OS versions :
Developing iPhone Apps with iOS4 SDK, Deploying to 3.x Devices : Base SDK and iPhone OS Deployment Target

Related

AVAssetWriter fails once App goes in background

I am working on iOS app in which i am creating video from images. I am using AVAssetWriter to achieve this. Everything works fine. But When app goes in background and switched back, the video writing fails. AVAssetWriter's finishWritingWithCompletionHandler is not getting called when i switch back to app.
May be duplicate of AVAssetWriter fails when Application enters Background during Rendering , but i am not getting any help from there.
Any idea for this?
Thanks
This answer is based on the assumption that you want the video to continue rendering while in the background.
I fixed this in my app doing by asking the OS to grant the app background task permisions (for a limited amount of time). This answer might help you too
iOS generating a video in the background task
#property (nonatomic,assign) UIBackgroundTaskIdentifier __block backgroundRenderingID;
UIApplication *app = [UIApplication sharedApplication];
_backgroundRenderingID = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:_backgroundRenderingID];
_backgroundRenderingID = UIBackgroundTaskInvalid;
}];
Don't forget to let go once you are done!
[[UIApplication sharedApplication] endBackgroundTask:_backgroundRenderingID];

How to make an App working in an background?

I am developing an application, in which I am fetching some photos from the XML link using NSXMLParser, so it takes some time to load images into view, while loading if I click on the home button in iPhone (device) and open the application again, the App crashes. I didn't know how to make my app to be able to run also in background state. I googled and found, "App States and Multitasking" but i can't able to make it in my application. Any solutions or links will be appreciated.
Try This
UIBackgroundTaskIdentifier backgroundTask = 0;
UIApplication *application= [UIApplication sharedApplication];
backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:backgroundTask];
}];
use this code in your application at initial method
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//call your upload method
}

Network disconnect issue when iOS screen locks

In iOS 5 When Application Enter background wi-fi connection is lost.
But I want to use wi-fi connection for the next 4-5 minutes before the device sleeps as some tasks can be performed within 4-5 minutes of application enter background.
I think this can be accomplished by using beginBackgroundTaskWithExpirationHandler:, but i am not able to solve the problem
just disable iPhone to go to sleep mode
-(void) sleepModeDisable{
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
}
call this function every 10 second, this might help u
The way I handle this is to use beginBackgroundTaskWithExpirationHandler for every network request I'm sending.
This way I make sure that all my networking will completed even if my app moved to background.
I'm usually using one singleton object to handle all network request, so before the request is sent I call
- (void)startBackgroundTask
{
// ask for extra time if this is called when app go to suspended
UIApplication *application = [UIApplication sharedApplication];
_bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you.
// stopped or ending the task outright.
[application endBackgroundTask:_bgTask];
_bgTask = UIBackgroundTaskInvalid;
}];
}
And after I get a response (success/failure) or if I canceled the request, I call
- (void)stopBackgroudTask
{
UIApplication *app = [UIApplication sharedApplication];
if (_bgTask != UIBackgroundTaskInvalid) {
[app endBackgroundTask:_bgTask];
_bgTask = UIBackgroundTaskInvalid;
}
}
* Don't forget to define UIBackgroundTaskIdentifier *_bgTask;
Also if you are planning to make a massive use of Wi-Fi you should set the Application uses Wi-Fi key in your plist file to YES, otherwise your Wi-Fi will be shut done after 30 minutes even if your app is running.
No rocket science here, this is intended behavior in iOS that to save battery the Wi-Fi shuts off when phone is locked UNLESS you tell iOS that your app needs a persistant Wi-Fi, then it wont close it for you when your app is running.
For that just add UIRequiresPersistentWiFi to your info.plist and mark it YES
Documentation

Application delegates are not calling while application entered into background

I am implementing an iPhone application.I am downloading data from server by using asynchronous request in the application.If, I Press the home button, My application delegate is not calling directly.After completion of data downloading from server, application delegate methods are calling.So, How can i get the immediate Delegate call in my application.
Any help can be appreciate.
Which delegate methods are you implementing? Can you post what you've tried (code-wise) here? Note that once your application has been moved to the background, you can only run short-term tasks to preserve battery life.
This example is provided by Apple:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you.
// stopped or ending the task outright.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
If you want to perform longer running tasks, you require special permissions, and even then can only perform a certain subset of actions. They are discussed here:
iOS App Programming Guide: App States and Multitasking

How to override exit action (iphone dev.)?

I need to write some information to file before exiting application. How can I do that?
Supposing your app supports multitasking (and you're on iOS 4 or above):
Override the applicationDidEnterBackground method in your app delegate, and do like the follwing:
- (void)applicationDidEnterBackground:(UIApplication *)application {
bgTask = [ [UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//do whatever writing you like
if (bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
Implement the following method in your App Delegate:
- (void)applicationWillTerminate:(UIApplication *)application
Start with Preserving the State of Your Application’s User Interface on Apple's Developer site. Read about the methods applicationDidEnterBackground: and it's related methods like applicationWillResignActive, etc. One thing to keep in mind when implementing any of these application delegate methods is that you don't have a lot of time to do stuff.
One way to avoid the race condition of trying to write out some data while the app is being backgrounded or exiting is to write it out when it changes during the normal course of your app running. Then, it's always correct "on disk."