Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 7 Background Modes - Not For App Store (No Rules Apply)

For the bounty, I am not interested in GPS or audio background modes as the former uses too much of the battery and the latter prevents any other audio from being used, otherwise facing audio interruption, thus ending background processes. I will need a way to be continuously processing in the background, so background modes that trigger occasionally are also out of the question.

If there is some way to run the application in the background, even by ignoring Apple's rules, I am interested in trying it. If the answer is VOIP, I am unsure where to begin the implementation, as all of my research has come up too high level or as a failure. How will my application be able to run in the background using the VOIP background mode. Without any added code, the application refuses to run in the background.


I know that with iOS 7, background modes have changed again. I would like to be able to run my application (that will never need to be approved on the iOS App Store) in the background. I would also like to be able to stop execution in the background until a specific time in the future.

For example, I would like it to run a process for 15 minutes, schedule the next task and then sleep until that time. For now, I've had to run a silent track in the background for background processing, but I would like to be able to have the application truly sleep during that time - also, playing real music or making a phone call are "handy features" of the iPhone and I don't like losing them.

I know there is also GPS, but that consumes an enormous amount of battery. The other background modes don't seem to give full control of background processing and timing to the application and leave a large portion of the timing and execution duration to the OS.

What I need is to be able to have my application process in the background for minutes at a time and then sleep until a fairly specific interval and continue processing. Is this possible with a better approach than I am currently using?

I've seen that VOIP used to be a possibility, but I'm not sure that it will work, as I don't need the application to run one simple task in the background, but rather to continue whatever was running in the foreground before the application was pushed to the background. Also, individual tasks could take upwards of 1 hour to complete, so they won't be able to transfer when the background task expires. All of my assumptions are based off this thread.

like image 665
RileyE Avatar asked Feb 08 '14 06:02

RileyE


1 Answers

Edit: There seems to be a terrible drop off rate with this method. At random, the recursion will seemingly fail for seemingly no reason (maybe a system timeout on execution?). If I place the recursion before ending the background task, the OS kills my application, but if I put it after, it occasionally seems to stop the background tasks at some point. I have seen it stop in the middle of my "allotted background time", as well.

In short, the below method does seem to run indefinitely, but not infinitely. Is there either a way to make the runtime guaranteed to be infinite or another solution?


It seems that using VOIP was leagues easier than I had first thought.

All that is required to run my application indefinitely (unfortunately sleeping is not an option) is to add voip to the selected Background Modes, either in the plist or in Target's Capabilities. After that, adding and running this code once, in an object that is never deallocated (your AppDelegate works nicely here), will allow for infinite background processing time:

- (void)infiniteBackgroundLoop
{
    __block UIApplication *applicationBlockReference = [UIApplication sharedApplication];
    __block AppDelegate *appDelegateBlockReference = self;
    __block UIBackgroundTaskIdentifier backgroundTask = [applicationBlockReference beginBackgroundTaskWithExpirationHandler:^
                                                         {
                                                             [applicationBlockReference endBackgroundTask:backgroundTask];
                                                             backgroundTask = UIBackgroundTaskInvalid;
                                                             [appDelegateBlockReference infiniteBackgroundLoop];
                                                         }];
}

In order to allow sleeping indefinitely, add a break to the recursion.

like image 87
RileyE Avatar answered Oct 22 '22 04:10

RileyE