iOS 9:在timout之前,beginBackgroundTaskWithExpirationHandler被调用

我正在进行VOIP呼叫,并添加了对iOS <10的支持。对于应用程序处于后台的传入VOIP呼叫,我正在使用UILocalNotification(在iOS 10中不推荐使用)。

要拨打电话60秒(或1分钟),我使用此代码

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; } } 

将后台进程时间延长至1分钟,并且在iOS 10.1.1(iPhone)中运行,但不在iOS 9.3.5(iPad)中运行。 不知何故处理程序调用30-33秒?

更新:

我试图评论这个代码:

 self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{ NSLog(@"ALVOIP : BACKGROUND_HANDLER_NO_MORE_TASK_RUNNING."); [application endBackgroundTask:self.backgroundTask]; self.backgroundTask = UIBackgroundTaskInvalid; }]; 

我仍然能够做30-33秒,即我不知道为什么这是行不通的?

我build议你把代码放在这个结构中,并使用这个代码

 -(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 }); }); } 

当你正在build立一个VOIP应用程序,在info.plist你应该能够设置UIBackgroundModesvoipUIApplicationExitsOnSuspendNO来允许后台任务。

查看“声明您的应用程序支持的后台任务”上的这个苹果帮助页面以获取更多信息。

当我最后build立一个在后台运行的应用程序(尽pipe它是用于后台定位服务,而不是用于一个voip应用程序),我不得不放弃在应用程序商店列出关于应用程序使用过度电池寿命的免责声明。 我不知道这是否有关了。

也看到这个答案 。

我会build议你安排几个UILocalNotification,每个都有一个增加的fireDate,然后设置你的UILocalNotification声音最后一个增加的时间间隔。 例如,说你的声音可以持续20秒,然后你安排3个UILocalNotification与fireDate在0,+ 20,+ 40秒。

当然,如果用户接听你的电话,你需要取消剩余的UILocalNotification。