dispatch_after is limited to 10 seconds?

五迷三道 提交于 2019-12-02 06:54:05

问题


I'm developing an app which is running in background. Sometimes I need to tell the user that something is happenning so I play a sound a certain number of times. To do that I made a timer but the problem is that It cannot exceed 10s of the total delayed time, after that, there are no more sounds (but the app is still running). I've checked this behavior in foreground mode and it works perfectly.

This is my code when I need to inform the user:



    AudioServicesPlaySystemSound(alarma);
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    numAlarm = 1;  
    NSTimeInterval delay_in_seconds = 2.0;
    dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    dispatch_after(delay,queue,^{
        [self fiBGTemps:ALARM];
    });

and the "fiBGTemps" is something like this,


- (void)fiBGTemps:(int)sender
{
    switch (sender){
        case TEMP_SCAN:
            (…)
            break;
        case ALARM:
            if (numAlarm>0 && numAlarm&ltNUM_ALARM)
            {
                AudioServicesPlaySystemSound(alarma);
                AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                NSTimeInterval delay_in_seconds = 2;
                dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW,delay_in_seconds*NSEC_PER_SEC);
                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
                dispatch_after(delay,queue,^{
                    [self fiBGTemps:ALARM];
                });
                numAlarm++;
            }
            break;
    }
}

Is that behavior normal? Am I missing something?

Thanks

Kanick


回答1:


Problem solved.

This is what happens. When an app is running in background and and it is executed a task, this task is running in background as well but the system allows only a certain amount of time (10s apron.) in order to safe battery. So it is only for a specific tasks (localization, download, etc.).

I my case I need a little more time so the solution is to define the task as a UIBackgroundTask in such a way that will be the task who notify the system when it is completed and thus can be terminated.

this is the code where it is called the task:



    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier background_task;
    background_task = [application beginBackgroundTaskWithExpirationHandler: ^{
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self fiBGTemps:@(ALARM)];
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    });

And here you can see the discussion on the Apple Forums where they explain this better than me.

AppleForums discussion

I hope this helps.

Kanick




回答2:


You can try with re-setting the delay value after it exceed 10s of the total delayed time or may be after it has played sound for certain amount of time.




回答3:


I suspect that chaining asynch blocks to play sounds at regular intervals is a bit of an overkill. Perhaps something simpler along the following lines would be easier to understand and maintain:

// To initiate the alarm:
[self fiBGTemps: ALARM];

- (void)fiBGTemps:(int)sender
{
    switch (sender) {
       ...
       case ALARM:
           dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
                int count = 0;
                while (count < NUM_ALARM /* AND not interrupted by user? */) {
                    sleep(2);
                    AudioServicesPlaySystemSound(alarma);
                    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
                    count++;
                }
            });
            break;
        ...
    }
}


来源:https://stackoverflow.com/questions/16295953/dispatch-after-is-limited-to-10-seconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!