我在stackoverflow中发现了大量关于NSTimer
在后台运行的帖子。
但是我没有找到任何解决方案。
在我的应用程序中,我在后台播放声音,并设置计时器以在达到该时间时停止音乐。
所以我需要运行我的NSTimer
背景(意味着当主页按钮点击并睡眠iPhone时)。
我该怎么做?
答案 0 :(得分:29)
// NSTimer run when app in background <br>
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
loop = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(Update) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];
这就是你想要的?。
答案 1 :(得分:3)
计时器仅存在于您的应用程序中。所以(除了一个非常小的窗口)当你的应用程序被发送到后台时,计时器就不能再发射了。
(音频一直在运行,因为它由系统播放,而不是由您的应用播放。)
所以你不能为此目的使用计时器。
您可以做的事情 - 正如iPatel建议的那样 - 使用本地通知。这将暂时唤醒您的应用,让您停止播放音乐。
答案 2 :(得分:2)
- (void)btnSetupNotificationClicked:(id)sender
{
UILocalNotification* pOrderCompletedNotification=[[UILocalNotification alloc] init];
if(pOrderCompletedNotification!=nil)
{
[pOrderCompletedNotification setFireDate:[[NSDate alloc] initWithTimeIntervalSinceNow:5.00]];
// [pOrderCompletedNotification setApplicationIconBadgeNumber:1];
[pOrderCompletedNotification setTimeZone:[NSTimeZone systemTimeZone]];
[pOrderCompletedNotification setSoundName:@\"OrderCompleted.m4a\"];
[pOrderCompletedNotification setAlertBody:@\"Order Completed\"];
[pOrderCompletedNotification setAlertAction:nil];
[pOrderCompletedNotification setHasAction:NO];
UIApplication* pApplication=[UIApplication sharedApplication];
if(pApplication!=nil)
{
[pApplication scheduleLocalNotification:pOrderCompletedNotification];
}
else
{
NSLog(@\"Application singleton allocation error.\");
}
[pOrderCompletedNotification release];
[pApplication release];
}
else
{
NSLog(@\"Local notification creation error.\");
} // if
}
答案 3 :(得分:2)
使用Swift
let app = UIApplication.sharedApplication()
app.beginBackgroundTaskWithExpirationHandler(nil)
let timer = NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector:"DoSomethingFunctions",
userInfo: nil,
repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
答案 4 :(得分:0)
我知道这篇文章比较老,但是最近我遇到了这个问题,在弄清楚这个问题时遇到了一些麻烦。这是我从Swift 5开始提出的解决方案。它结合了RunLoop和Timer类,并在下面的链接中提供了有关它们的信息。
使用计时器
使用运行循环
示例代码:
class AMSleepTimerUtil: NSObject {
static let shared = AMSleepTimerUtil()
fileprivate var sleepTimer: Timer?
/// Initialize the timer to trigger a function to execute after a duration of time
/// - Parameter seconds: the time delay until the selector function executes
/// - Returns: true if sleep timer were successfully initialized
func createTimerToStopMusic(at seconds: TimeInterval) -> Bool {
let fireAtDate = Date(timeIntervalSinceNow: seconds)
stopSleepTimer()
self.sleepTimer = Timer(fireAt: fireAtDate,
interval: 0,
target: self,
selector: #selector(pauseMusic),
userInfo: nil,
repeats: false)
guard let sleepTimer = sleepTimer else { return false }
RunLoop.main.add(sleepTimer, forMode: .common)
return true
}
func pauseMusic() {
guard let audioPlayer = AMNowPlayingViewController.sharedInstance()?.audioPlayer else { return }
audioPlayer.pause()
}
/// Used to reset the sleep timer before initializing a new timer if the user clicks the "Set Timer" multiple times
func stopSleepTimer() {
if sleepTimer != nil {
sleepTimer?.invalidate()
sleepTimer = nil
}
}
func sleepTimerIsActive() -> Bool {
return self.sleepTimer != nil
}
}
答案 5 :(得分:-2)
当您运行NSTimer
时,@selector
方法本身将确定您想要在后台或主线程中运行。
初始设置:
self.scanTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(manageMethod) userInfo:nil repeats:YES]; //@property (nonatomic, strong) NSTimer *scanTimer
您希望在后台运行的案例:
-(void)manageMethod
{
dispatch_queue_t queue = dispatch_queue_create("com.mysite.thread1",NULL);
dispatch_async(queue,^{
//run in background
});
}