我用谷歌搜索了几个小时,但找不到任何信息,如果有任何方法可以在应用程序在后台运行时保持正在运行的NSTimer活动?请帮帮我,当应用程序进入后台时,运行一个功能,每个SEC检查闹钟时间是否等于当前时间,然后播放音频并打开关闭闹钟页面如果有人知道闹钟应用程序的开源和后台运行,请与我分享这里我尝试这个,但这是不工作
- (void)applicationDidEnterBackground:(UIApplication *)application
{
inBackground=YES;
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (inBackground == YES) {
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:@selector(checkAlert) userInfo:nil repeats:YES];
}
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
-(void)checkAlert
{
NSLog(@"Chalaaaaaa");
NSString *checkAlarmOnOff = [defaults stringForKey:@"setAlarm"];
// Switch Alarm From Setting page
NSString *SwitchAlarm=[defaults stringForKey:@"setSwitchAlarm"];
if([SwitchAlarm isEqualToString:@"ON"])
{
if([checkAlarmOnOff isEqualToString:@"YES"])
{
if(![alarmRun isEqualToString:@"Yes"])
{
NSString *getAlarmTime = [defaults stringForKey:@"setAlarmTime"];
NSLog(@"AA-%@",getAlarmTime);
NSLog(@"BB-%@",globalClockTime);
if([getAlarmTime isEqualToString:globalClockTime])
{
[self MusicAction];
[_audioPlayer play];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alarm" message:@"Alarm On" delegate:self cancelButtonTitle:@"Off" otherButtonTitles:nil, nil];
[alert show];
alarmRun=@"Yes";
}
}
}
}
}
请帮帮我,
调度本地通知将完成您想要的。使用日历和日期组件在今天的特定时间或其他特定日期的特定时间触发本地通知。
NSCalendar *calendar = [NSCalendar currentCalendar];
// Split the date into components but only take the year, month and day and leave the rest behind
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]]; // Current Date
// Build the date formatter
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"h:mm a"];
// Convert the string time into an NSDate
NSDate *time = [formatter dateFromString:@"1:59 PM"]; //your hour:minutes am/pm values
// Split this one in components as well but take the time part this time
NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];
// Do some merging between the two date components
dateComponents.hour = timeComponents.hour;
dateComponents.minute = timeComponents.minute;
// Extract the NSDate object again
NSDate *fireTime = [calendar dateFromComponents:dateComponents];
NSLog(@"Fire Time is FireTime %@", fireTime);
localNotification.fireDate = fireTime;
如果您在模拟器中检查它,那么它将打印TimeZone free日期/时间值。不用担心,通知将以设备的本地时区触发。
请注意,苹果肯定会拒绝任何滥用其后台政策的应用程序,所以这样做只会对个人和企业使用有用!
那么我们要如何滥用iOS后台政策呢?我们将把我们的应用程序声明为背景音乐播放器,但不播放任何音乐。
1)首先确保你的应用程序已经,在功能->背景模式打开和"音频和AirPlay"启用。同时确保导入AVFoundation
2)现在创建您的静音音乐文件。我成功地制作了一个一秒钟的沉默MP3文件。音频文件不一定是无声的,但是为什么要用一个随机的音频文件吓唬用户呢?将此文件添加到"支持文件"类别中。
3)添加一个属性到视图控制器,将保持静音音频播放器
Swift:
var player = AVPlayer()
Obj-c:
@property (nonatomic, strong) AVPlayer *player;
4)现在,您应该设置音频会话。我选择在演示应用程序中单个视图的视图控制器的viewDidLoad中执行此操作。
Swift:
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: .MixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
Obj-c:
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&sessionError];
类别AVAudioSessionCategoryPlayback是少数允许背景的类别之一。选项avaudiosessioncategoryoptionmixwiththothers将确保你的静音音频不会停止任何当前正在播放的背景音频,也确保当用户在未来播放音乐时,它不会启动你的后台任务。一个好的开发人员也会检查返回值和sessionError,但我不是一个好的开发人员。
5)现在为你的无声音频文件创建实际的播放器项目。如果你想用不同的方式嵌入音频文件,请随意调整。这里没有欺骗。
Swift:
let path = NSBundle.mainBundle().pathForResource("30sec", ofType: "mp3")
let item = AVPlayerItem(URL: NSURL(fileURLWithPath: path!))
player = AVPlayer(playerItem: item)
Obj-c:
AVPlayerItem *item = [AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@”silence” withExtension:@”mp3″]];
[self setPlayer:[[AVPlayer alloc] initWithPlayerItem:item]];
6)这是诀窍!这确保音频播放器在播放声音文件后保持活跃。另一种选择是保持循环静音轨道,但是为什么要浪费更多的CPU周期(和电池)呢?
Swift:
player.actionAtItemEnd = .None
Obj-c:
[[self player] setActionAtItemEnd:AVPlayerActionAtItemEndNone];
7)现在,无论何时您希望保持应用程序在后台,只需调用
Swift:
player.play()
Obj-c:
[[self player] play];
你的应用程序将继续工作,即使在用户切换应用程序。
NSTimer将不会在后台运行。使用beginBackgroundTaskWithExpirationHandler
并不能解决你的问题。有了后台任务,你的应用程序最多可以运行10分钟,然后会被杀死
你应该使用UILocalNotification
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = dateTime;
localNotification.alertBody = [NSString stringWithFormat:@"Alert Fired at %@", dateTime];
localNotification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
使用NSCalendar计算时间,并添加以下行:
localNotification.repeatInterval = NSDayCalendarUnit;