Ios X分钟后停止音频播放器

Ios X分钟后停止音频播放器,ios,objective-c,iphone,Ios,Objective C,Iphone,我正在开发一个音频应用程序。我必须完成的一项任务是在X分钟后(由用户定义)停止音频播放器,就像播放器睡眠一样 为此,我使用本地通知 这是我的自定义播放器中的代码: - (void)configureSleepTimer:(NSUInteger)seconds { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = [NSD

我正在开发一个音频应用程序。我必须完成的一项任务是在X分钟后(由用户定义)停止音频播放器,就像播放器睡眠一样

为此,我使用本地通知

这是我的自定义播放器中的代码:

- (void)configureSleepTimer:(NSUInteger)seconds {
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    localNotification.soundName = UILocalNotificationDefaultSoundName;

    NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:@[@"PlayerSleep"] forKeys:@[@"type"]];
    localNotification.userInfo = userInfo;

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    NSLog(@"Notification: %@", localNotification);
}
AppDelegate:

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    if ([[notification.userInfo valueForKey:@"type"] isEqualToString:@"PlayerSleep"]) {
        Player *player = [Player sharedInstance];
        [player stopPlayer];
    }
}
上述代码的问题在于,当应用程序在后台运行时,播放器不会停止

为了在后台运行,我检查应用程序何时进入后台模式,并检查是否存在本地通知。如果存在,我会启动一个1秒的计时器,将通知时间与实际日期进行比较,以便在需要时停止播放器

- (void)applicationDidEnterBackground:(UIApplication *)application {
    __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if ([[[UIApplication sharedApplication] scheduledLocalNotifications] count]) {
            NSTimer *t = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(sleepPlayer) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
            [[NSRunLoop currentRunLoop] run];
        }
    });
}

- (void)sleepPlayer {
    [[[UIApplication sharedApplication] scheduledLocalNotifications] enumerateObjectsUsingBlock:^(UILocalNotification *notification, NSUInteger idx, BOOL *stop) {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"];
        NSString *dateTimeStr = [formatter stringFromDate:[NSDate date]];
        NSString *notifDateStr = [formatter stringFromDate:[NSDate dateWithTimeInterval:-1 sinceDate:notification.fireDate]];

        if ([dateTimeStr isEqualToString:notifDateStr]) {
            Player *player = [Player sharedInstance];
            [player stopPlayer];
            [[UIApplication sharedApplication] cancelLocalNotification:notification];

            NSLog(@"************************** Player Sleeped");
        }
    }];
}

它可以工作,但是,我不喜欢最后一段代码。有更好的方法吗?

解决方案1。我已经实现了类似的功能,但不是您想要的。我所做的是,当曲目结束时,检查睡眠时间,如果超过,停止播放器,这是用播放器实现睡眠计时器的被动方式。也许,这个解决方案也适用于你

解决方案2。如果你的应用程序支持后台模式,即在后台播放音频,你可以使用
initWithFireDate:
的初始化方法
NSTimer
将计时器(无需开始后台任务)安排在准确的时间调用。这样做,您的计时器将不会被调用的每一秒,但在准确的时间

希望这是有帮助的。祝你好运


注意:请记住,这两种解决方案都要求您的应用程序注册为后台模式,至少是音频模式。

解决方案1对我没有用处。音频无法或无法完成。可以是曲目或广播流。从现在起,我将尝试混合使用您的解决方案2和我当前的实现。顺便说一句,当然需要启用后台模式。