Iphone 后台服务是;允许在后台继续运行;。那为什么';我不能让它工作吗?

Iphone 后台服务是;允许在后台继续运行;。那为什么';我不能让它工作吗?,iphone,objective-c,ios,cocoa-touch,Iphone,Objective C,Ios,Cocoa Touch,我的应用程序确实满足使用ui背景模式设置为“应用程序播放音频”的要求。我的应用程序播放MPMusicLayer控制器IPODMusicLayer类中的音乐。我试图实现的是允许用户设置一个计时器,让音乐停止。我对此有意见。我在applicationidenterbackground方法中实现了后台任务,如下所示: - (void)applicationDidEnterBackground:(UIApplication *)application { UIDevice* device = [

我的应用程序确实满足使用
ui背景模式
设置为“应用程序播放音频”的要求。我的应用程序播放
MPMusicLayer控制器IPODMusicLayer
类中的音乐。我试图实现的是允许用户设置一个计时器,让音乐停止。我对此有意见。我在
applicationidenterbackground
方法中实现了后台任务,如下所示:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    UIDevice* device = [UIDevice currentDevice];
    BOOL backgroundSupported = NO;
    if ([device respondsToSelector:@selector(isMultitaskingSupported)]) {
        backgroundSupported = device.multitaskingSupported;
    }

    if (backgroundSupported) {
        UIApplication*    app = [UIApplication sharedApplication];
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                if (bgTask != UIBackgroundTaskInvalid) {
                    [app endBackgroundTask:bgTask];
                }
            });
        }];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_async(dispatch_get_main_queue(), ^{
                if (bgTask != UIBackgroundTaskInvalid) {
                    if (rootController.sleepTimer != nil)
                    self.sustainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self  selector:@selector(checkTimeRemaining) userInfo:nil repeats:YES];    
                }

            });
        });
    }
}
使用
checkTimeRemaining
方法:

-(void)checkTimeRemaining{
    NSTimeInterval totalSeconds = rootController.timerSetInSeconds.doubleValue;
    NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:rootController.startDateforSleepTimer];
    NSTimeInterval remainingTime = totalSeconds - elapsedTime;
    NSLog(@"remaining time %f",remainingTime);
    if (remainingTime <= 0) {
        [self.musicPlayer pause];
        [sustainTimer invalidate];
        self.sustainTimer = nil;
    }
}
-(无效)检查剩余时间{
NSTimeInterval totalSeconds=rootController.timerSetInSeconds.doubleValue;
NSTimeInterval elapsedTime=[[NSDate date]timeIntervalSinceDate:rootController.StartDateForSleepTime];
NSTimeInterval remainingTime=总秒数-延时;
NSLog(@“剩余时间%f”,剩余时间);

如果(remainingTime您无法使其工作,因为音频背景模式设置允许音频处理在后台继续,直到音频停止。它不会授予非音频内容(如BackgroundTaskWithExpirationHandler)任何特殊权限以继续


但是,如果您将时间记录放在音频队列或RemoteIO音频单元缓冲区回调中,只要音频继续播放,它就会一直被调用。

因为
beginBackgroundTaskWithExpirationHandler
只允许您执行有限长度的任务,所以您的计时器仍被限制在苹果规定的10分钟时间限制内另一方面,io框架内部允许设备在后台播放音频,直到用户停止播放或音频结束

当UIBackgroundModes键包含音频值时,系统的 媒体框架会自动阻止相应的应用程序 当它移动到背景时被暂停。只要它是 播放音频或视频内容时,应用程序将继续在 但是,如果应用程序停止播放音频或视频,则 系统暂停它


您好,谢谢您回复我。AppStore中有一些应用以某种方式实现了这一点。它们使用iPodMusicLayer控制器播放音乐,一旦用户设置时间并锁定设备,它将在x分钟/小时后停止音乐。它们是如何实现的?我陈述的最后一行“或音频结束”是您探索如何结束音频的提示:)。查看@hotpaw2的建议。如果音频队列不断回叫您的代码,您应该能够停止它。抱歉,没有完全理解。感谢您的帮助。嗨,谢谢。在您描述的情况下,我还会使用
iPodMusicPlayer
控制器吗?学习如何实现t的最佳起点是哪里他的?你认为一些睡眠计时器应用程序就是这样实现的吗?他们仍然可以使用iPod音乐控制器。