iOS 9 : beginBackgroundTaskWithExpirationHandler is getting called before timout
Asked Answered
A

3

0

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?

Adiana answered 16/2, 2017 at 6:12 Comment(0)
H
0

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
    });
});
}
Hyps answered 16/2, 2017 at 6:47 Comment(3)
I need to extend time when app is background not to change any thing in view controllerAdiana
@Abhishek Thapliyal use ur logic inside this methodHyps
Not understanding how this will adjust in my code. I don't need any vie controller change or any call only call a timerAdiana
A
0

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.

Arabele answered 16/2, 2017 at 12:53 Comment(4)
Thanks for your answer but still getting max 36 secs in iOS 9 :(Adiana
Also 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; }]; this not working and hence not extending time as after commenting this i m still able to do 30-33 secsAdiana
@AbhishekThapliyal If you are trying to recreate the timer while the app is suspended to extend background processing time, I think that behaviour stopped working since iOS 7. I am currently working on a project where I need to look into background tasks again so I will let you know what I find.Arabele
@AbhishekThapliyal Sorry to ask, but can you confirm you are building to a real device and not just the simulator?Arabele
M
0

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.

Meantime answered 20/2, 2017 at 7:38 Comment(4)
but i want play incoming call sound also for local notificationAdiana
I will say using different sounds for different purposes may be a good idea.Meantime
i mean with local notification i need to play sound also for 1 minuteAdiana
3 notifications, each 20 seconds, then it is 60 secondsMeantime

© 2022 - 2024 — McMap. All rights reserved.