Keep app in background for 10 mins while doing nothing in background - iphone

I have this code in my app -
- (void)applicationDidEnterBackground:(UIApplication *)application
{
...
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
if (bgTask != UIBackgroundTaskInvalid)
{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}];
//NO MORE CODE AFTER THAT
}
I just want to extend my app's duration of running in background to handle some events from an external source.
By using this code the app, sometimes the app is crashing with the logs -
[app-name] has active assertions beyond permitted time
can anyone help me with this?
Even though its crashing, it wont affect the user. The user wont get to know about the crash since the app is in background. I'm just worried about rejection by the app store review. Need urgent help! :(
EDIT :
My app is communication to an external device via asynchronous TCP socket. With above code when I send my app to the background it recieves data for an additional 10 mins. After 10 minutes when I bring the app to the foreground the app hasn't closed yet, but it shows that the socket connection has disconnected. So as soon as the app comes to foreground AFTER 10 mins, it starts re-establishing the connection.
This happens in about 80% of the test cases. Remaining 20% result in the aforementioned crash.

What sort of work are you doing on the main thread whilst in the background? If you're blocking it, the expiration handler block won't be called, viz:
A handler to be called shortly before the application’s remaining
background time reaches 0. You should use this handler to clean up and
mark the end of the background task. Failure to end the task
explicitly will result in the termination of the application. The
handler is called synchronously on the main thread, thus blocking the
application’s suspension momentarily while the application is
notified.
This will cause the watchdog to maul you as having failed to terminate your background tasks in time.

Related

multiple image uploading to server using soap based web service

I am trying to run image uploading using soap based web service and doing this i face 2 key issue in my app.
Issue 1:- When app uploading multiple images to server and at that time if my application goes in background state than at that time my is stop executing (application suspended state). when i my app goes back from background to foreground state than it again resume my background thread.
Issue 2:- When i try to upload 160-170 images on server from device gallery. i received memory warning after uploading 60-70 images on server. i handle that method and try to free some memory within application and i again start my thread at that time my application crashed. //->> for 2nd issue i add 3 different web service and its too long code so i am not going to share it here. when i check on instrument it generally run on max 2 to 2.5 MB in live bytes but when i uploading thread start it gradually increasing and at some pick point i received received memory warning. my code contains feature of ARC but still i got memory warning issue.
code for issue 1:-
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:#selector(isMultitaskingSupported)])
{
backgroundSupported = device.multitaskingSupported;
}
//NSLog(#"backgroundSupported: %d", backgroundSupported);
if (backgroundSupported)
{
_IsBackground = TRUE;
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),
^{
while (_IsBackground)
{
//// it contineous run my application within this state.
}
NSLog(#"Background loop ended");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
}
1 )
Apple cares very much about battery life on iPhones and iPads, so they are very strict about what can run in the background (which is to say, not too much).
With the current shipping versions of iOS, you only have about 5 seconds to clean up or properly suspend things when your application receives a call to the "applicationDidEnterBackground:" delegate method.
You need to come up with a way to upload your images via a background thread while your app is in the foreground. That means that the only time you can upload images is while your app is visible to the user.
More information can be found in this closely related question.
2 )
For your second issue, it's pretty clear that you are not properly releasing (or setting to "nil", or resetting) some variables that are being used in the process of uploading multiple images, which is why you see memory usage increasing and increasing and eventually killing your app.
You already know about Instruments, but it sounds like you need to get even more familiar with tracking down memory usage and which things in memory are taking up more and more space.

ios voip app run only 10 min in background

I am creating a voip application for iPhone and iPad family in which I have done following things :
Added the UIBackgroundModes key in the plist file with values 'audio' and 'voip'.
Create NSInputStream and NSOutputStream with tag NSStreamNetworkServiceTypeVoIP and scheduled them in runloop of another thread(not main thread).
Created a background task in applicationDidEnterBackground.
Added setKeepAliveTimeout handler (timeout value 600 sec).
Application relaunches when code in handler of setKeepAliveTimeout is called.
Application relaunches if I dont put setKeepAliveTimeout handler ,but tries to send any signal to app after suspension(10 mins in background is completed).
I have tried almost everything that came in my mind, Need pointers towards the solution Thanks in advance,
It is the duty of the setKeepAliveTimeout handler to care about the connection. Thus, you should use an alive interval that is shorter than the timeout time of your connection.

how can I run iOS4 app in the background?

I'm developing an app for iOS4. The application is made of two main components, one that is supposed to run in the background and one that is constantly displayed on screen and takes data from the first one. Here's the problem: the first component works just fine until it is put in the background. At that point it stops sending data. Why is that? Is there any workaround?
Thank you.
If you're not using VoIP, Audio or GPS you can only use the task completion mode (which is limited to 10 minutes in background).
To do that you have to tell the OS you want to start a task with:
UIApplication* app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
and when you're done, you can end it with:
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
Remember that if your running longer than 10 minutes, the OS will kill your app.
In applicationDidEnterBackground: you have the problem that your code still blocks the main thread, which is why it's killed when you exit the app.
If you want to start executing code in applicationDidEnterBackground: you should begin the background task and dispatch whatever it is you want to do with dispatch_async(queue, block_with_your_code);
You can read more on it here
There is non you are only allowed to run VOIP, Audio or Locationbased apps in the background.
So unless you apps falls in one of those categories there is no way to keep you app working in the background.
Apple allows only certain types of apps to run in the background, like navigation and VOIP apps, to name just two. But even those are limited to only the necessary tasks.
The only alternative are "longrunning background tasks" - this allows an app to continue working in the background for up to ten minutes (the exact duration of this "grace period" is subject to change, afaik). You may obvserve this on apps like Hipstamatic, which will finish postproduction on images even when the app is being moved to the background.
As others have pointed out there's no real way to do this, but there is a workaround some apps use. You basically play a track from the users iPod library in the background, which enables your app to stay working in the background for a longer time. You can read more about it on Tapbots' site.

What does "UIBackgroundTaskInvalid" mean?

I'm developing iPhone app which runs in the background(iOS4), and refer "Completing a Finite Length Task in the Background" written by Apple at the following url
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH5
Then I've been able to implement background tasks.
(Of course, I see that application has 10min time limitaiton.)
However, I still can't understand what "bgTask = UIBackgroundTaskInvalid;"(Line7,16 of Listing 4-2) means.
In my opinion, the line shown above has never been reached.
Because there is "endBackgroundTask:" before that and the background task will be ended.
In fact, when I checked with xcode debugger, this thought may be true and not reach at Line7, 16.
If so, is this line redundant?
Or is there any reason to have to be written?
I would appreciate any help about this.
Thanks in advance.
The code in the block is called if the 10 minutes runs out before the application has completed its background task.
The code in this block must call endBackground: to indicate the situation is acknowledged and accepted by the application - if it doesn't the application will be terminated. Note that calling the method doesn't terminate the application - it simply indicates to the OS that the background task execution has completed.
The second line is simply to reset bgTask to a neutral value, rather than leaving it set id of a task that no longer exists. It's a tidiness thing rather than being essential.
(I wouldn't be surprised if the second line isn't executed until the application is next foregrounded, since once background execution ends the app doesn't get any CPU time to run. Haven't tested this, though)
Key to understanding it is that instead of having a completionHandler you have an expirationHandler. It only executes that line as a 'clean up' of your code taking toooo long.
To clean up it has nuke/kill/end your background task. So first it has to stop it with:
[application endBackgroundTask:bgTask];
Then it also sets a flag on the task so it won't be executed again.
bgTask = UIBackgroundTaskInvalid;
The reason you see it twice in the code is because either:
It successfully runs in the background and gets finished in the dispatch block...so you need to inform the app that hey I'm done.
You don't finish in the background but the app is like times up! You gotta go...clean up after yourself by doing a [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid;

How to keep an iPhone app running on background fully operational

first of all, I know there is only support for voip, audio and location apps to run in background and that they will run just while the audio is been played or while using location services, etc.
What I want to know is if there is a way to keep my app running on background fully operational, doesn't matter the impact on battery's life.
That way the user of my app can select from settings to keep alive the app whenever he wants and just for the amount of time he wish. e.g if he is waiting for something that requires the app to be running, after receiving the messages he can turn off the keep alive functionality.
I don't know if this is possible but I had read some post that say so but unfortunately they didn't say how to =(
UPDATE: In this tutorial, I found that Acrobits has two apps on the Apple Store that "can force the application to stay alive and awake in the background". So there is a way to do this?
From ioS 7 onwards, there are newer ways for apps to run in background. Apple now recognizes that apps have to constantly download and process data constantly.
Here is the new list of all the apps which can run in background.
Apps that play audible content to the user while in the background, such as a music player app
Apps that record audio content while in the background.
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
You can declare app's supported background tasks in Info.plist using X Code 5+. For eg. adding UIBackgroundModes key to your app’s Info.plist file and adding a value of 'fetch' to the array allows your app to regularly download and processes small amounts of content from the network. You can do the same in the 'capabilities' tab of Application properties in XCode 5 (attaching a snapshot)
You can find more about this in Apple documentation
You can perform tasks for a limited time after your application is directed to go to the background, but only for the duration provided. Running for longer than this will cause your application to be terminated. See the "Completing a Long-Running Task in the Background" section of the iOS Application Programming Guide for how to go about this.
Others have piggybacked on playing audio in the background as a means of staying alive as a background process, but Apple will only accept such an application if the audio playback is a legitimate function. Item 2.16 on Apple's published review guidelines states:
Multitasking apps may only use
background services for their intended
purposes: VoIP, audio playback,
location, task completion, local
notifications, etc
If any background task runs more than 10 minutes,then the task will be suspended and code block specified with beginBackgroundTaskWithExpirationHandler is called to clean up the task. background remaining time can be checked with [[UIApplication sharedApplication] backgroundTimeRemaining].
Initially when the App is in foreground backgroundTimeRemaining is set to bigger value. When the app goes to background, you can see backgroundTimeRemaining value decreases from 599.XXX ( 1o minutes). once the backgroundTimeRemaining becomes ZERO, the background task will be suspended.
//1)Creating iOS Background Task
__block UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
//This code block is execute when the application’s
//remaining background time reaches ZERO.
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//### background task starts
//#### background task ends
});
//2)Making background task Asynchronous
if([[UIDevice currentDevice] respondsToSelector:#selector(isMultitaskingSupported)])
{
NSLog(#"Multitasking Supported");
__block UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
//Clean up code. Tell the system that we are done.
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
}];
**//Putting All together**
//To make the code block asynchronous
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//### background task starts
NSLog(#"Running in the background\n");
while(TRUE)
{
NSLog(#"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]);
[NSThread sleepForTimeInterval:1]; //wait for 1 sec
}
//#### background task ends
//Clean up code. Tell the system that we are done.
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
});
}
else
{
NSLog(#"Multitasking Not Supported");
}
For running on stock iOS devices, make your app an audio player/recorder or a VOIP app, a legitimate one for submitting to the App store, or a fake one if only for your own use.
Even this won't make an app "fully operational" whatever that is, but restricted to limited APIs.
Depends what it does. If your app takes up too much memory, or makes calls to functions/classes it shouldn't, SpringBoard may terminate it. However, it will most likely be rejected by Apple, as it does not follow their 7 background uses.
May be the link will Help bcz u might have to implement the code in Appdelegate in app run in background method ..
Also consult the developer.apple.com site for application class
Here is link for runing app in background