【发布时间】:2016-01-19 18:30:15
【问题描述】:
我正在开发一个音频应用程序。我必须完成的一项任务是能够在 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];
}
}
上面代码的问题是,应用在后台运行时播放器没有停止。
为了让这个在后台运行,我检查应用程序何时进入后台模式并检查是否存在本地通知。如果存在,我会触发一秒钟的计时器,将通知触发时间与实际日期进行比较,以便在需要时停止播放器。
- (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");
}
}];
}
它有效,但是,我不喜欢最后一段代码。有没有更好的方法?
【问题讨论】:
标签: ios objective-c iphone