iOS 9:在超时之前调用beginBackgroundTaskWithExpirationHandler

iOS 9:在超时之前调用beginBackgroundTaskWithExpirationHandler,ios,objective-c,uilocalnotification,uibackgroundtask,Ios,Objective C,Uilocalnotification,Uibackgroundtask,我正在进行VOIP呼叫,并为iOS

我正在进行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;
    }
}

但我仍然能够完成30-33秒,也就是说,我不知道为什么这不起作用?

我建议您将代码放入此结构中并使用此代码

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

在构建VOIP应用程序时,在info.plist中,您应该能够将
UIBackgroundModes
设置为
VOIP
,并将
UIApplicationExitsOnSuspend
设置为
NO
以允许后台任务

有关更多信息,请查看“声明应用程序支持的后台任务”

当我上一次构建一个在后台运行的应用程序时(尽管它是用于后台位置服务的,而不是用于voip应用程序),我不得不在应用程序商店中列出一条免责声明,说明该应用程序使用了过多的电池寿命。但我不确定这是否还有意义


另请参见上面的内容。

我建议您安排几个UILocalNotification,每个UILocalNotification都有一个递增的fireDate,而不是使用NSTimer,然后将UILocalNotification声音设置为最后一个递增的间隔。例如,假设您的声音可以持续20秒,然后您计划从现在起3个UILocalNotification,fireDate为0、+20、+40秒


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

我需要延长应用程序处于后台时的时间,以不更改视图中的任何内容controller@AbhishekThapliyal在此方法中使用您的逻辑,但不了解这将如何在我的代码中进行调整。我不需要任何vie控制器更改,也不需要任何调用,只需要调用一个计时器来获取答案,但在iOS 9中仍然可以获得最多36秒的时间:(我还尝试对以下代码进行注释:self.backgroundTask=[应用程序beginBackgroundTaskWithExpirationHandler:^{NSLog(@“ALVOIP:BACKGROUND\u HANDLER\u NO\u MORE\u TASK\u RUNNING.”);[application endBackgroundTask:self.backgroundTask];self.backgroundTask=UIBackgroundTaskInvalid;}];这不起作用,因此没有延长时间,因为在评论这一点后,我仍然能够做到30-33secs@AbhishekThapliyal如果您试图在应用程序挂起以延长后台处理时间的同时重新创建计时器,我认为这种行为自iOS 7之后就停止了。我目前正在进行一个项目,需要查看backgro再次下载任务,我会让你知道我发现了什么。@AbhishekThapliyal很抱歉问一下,但是你能确认你正在构建一个真正的设备,而不仅仅是模拟器吗?但是我想播放来电声音也是为了本地通知。我会说,为不同的目的使用不同的声音可能是个好主意。我的意思是,有了本地通知,我需要播放来电声音声音也会持续1分钟3次通知,每20秒一次,然后是60秒
-(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
    });
});
}