我在stackoverflow中发现了很多关于NSTimer
后台运行的帖子。
但是我没有找到任何解决方案。
在我的应用程序中,我在后台播放声音,并设置计时器以在到达该时间时停止音乐。
所以我需要运行我的NSTimer
背景(意味着当点击主页按钮和睡眠 iPhone 时)。
我怎样才能做到这一点?
我在stackoverflow中发现了很多关于NSTimer
后台运行的帖子。
但是我没有找到任何解决方案。
在我的应用程序中,我在后台播放声音,并设置计时器以在到达该时间时停止音乐。
所以我需要运行我的NSTimer
背景(意味着当点击主页按钮和睡眠 iPhone 时)。
我怎样才能做到这一点?
// 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];
这是你想要的吗?
计时器仅存在于您的应用程序中。所以(除了一个非常小的窗口)当你的应用程序被发送到后台时,计时器不能再触发了。
(音频继续运行,因为它是由系统播放的,而不是由您的应用程序播放的。)
因此,您不能为此目的使用计时器。
正如 iPatel 建议的那样,您可以做的是使用本地通知。这将短暂唤醒您的应用程序,让您停止播放音乐。
获取表单 [此问题] ( http://iphonedevsdk.com/forum/iphone-sdk-development/58643-keep-nstimer-running-when-app-is-in-background-multitasking.html )
- (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
}
使用斯威夫特
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)
我知道这篇文章相对较旧,但我最近遇到了这个问题并且在弄清楚它时遇到了一些麻烦。这是我在 Swift 5 中提出的解决方案。它结合了 RunLoop 和 Timer 类,在下面提供的链接中提供了有关它们的信息。
使用定时器
使用运行循环</p>
示例代码:
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
}
}
当您运行时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
});
}