i'm working on VOIP call and adding support to iOS < 10. For incoming VOIP call when app is in background, i'm using UILocalNotification (deprecated in iOS 10).
To make a call 60 secs (or 1 minute) i'm using this code
count = 0;
apnTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(showIncomingCall:)
userInfo:userInfo
repeats:YES];
self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"ALVOIP : BACKGROUND_HANDLER_NO_MORE_TASK_RUNNING.");
[application endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}];
-(void)showIncomingCall:(NSTimer *)timer
{
if (count < 60)
{
UIApplication *application = [UIApplication sharedApplication];
[application presentLocalNotificationNow:localNotification];
NSLog(@"Time Remaining: %f", [[UIApplication sharedApplication] backgroundTimeRemaining]);
count = count + 3;
return;
}
// TIMEOUT : STOP TIMER AND LOCAL NOTIFICATION BACKGROUND TASK
[self invalidateCallNotifying];
}
-(void)invalidateCallNotifying
{
[apnTimer invalidate];
if (self.backgroundTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
}
to extend background process time to 1 minute and it's working in iOS 10.1.1 (iPhone) but not working in iOS 9.3.5 (iPad). Somehow handler is invoking 30-33 secs?
UPDATE:
i tried to comment this code :
self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"ALVOIP : BACKGROUND_HANDLER_NO_MORE_TASK_RUNNING.");
[application endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}];
Still i'm able to do 30-33 secs i.e i don't know why this is not working?
I Would Suggest you to Put Code in this Structure and Use this Code
-(void)yourMethod
{
__block UIBackgroundTaskIdentifier background_task;
background_task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void){
[[UIApplication sharedApplication] endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Some Methods Calls
dispatch_async(dispatch_get_main_queue(), ^{
//View Controller Change
});
});
}
As you are building a VOIP application, in info.plist you should be able to set UIBackgroundModes
to voip
and UIApplicationExitsOnSuspend
to NO
to allow background tasks.
Check out this apple help page on "Declaring Your App’s Supported Background Tasks" for more information.
When I last built an application that ran in the background (albeit it was for background location services, not for a voip app), I had to put a disclaimer on the app store listing about the app using excessive battery life. I'm not sure if this is relevant anymore though.
Also see this answer on SO.
Instead of using an NSTimer, I will suggest you schedule several UILocalNotification, each has an increasing fireDate, then set your UILocalNotification sound last for the increased interval. For example, say your sound can last for 20 seconds, then you schedule 3 UILocalNotification with fireDate at 0,+20,+40 seconds from now.
Of course if user answers your call you need to cancel the remaining UILocalNotification.
来源:https://stackoverflow.com/questions/42266258/ios-9-beginbackgroundtaskwithexpirationhandler-is-getting-called-before-timout