如何让我的应用在后台运行 NSTimer?

Posted

技术标签:

【中文标题】如何让我的应用在后台运行 NSTimer?【英文标题】:How do I make my App run an NSTimer in the background? 【发布时间】:2012-03-02 11:48:47 【问题描述】:

我正在制作一个仅用于测试目的的基准应用程序。我不打算将它放到 App Store。

我需要的是我的 NSTimer 继续使用 UIBackgroundTaskIdentifier 在后台运行,将数据保存到 Core Data db,最后将数据推送到服务器(我正在使用 Parse),当然,在一定的时间间隔之后.

所以基本上,我没有发现任何适用于我的具体案例的问题。我这样设置我的 NSTimer:

    UIBackgroundTaskIdentifier bgTask;
UIApplication  *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^
    [app endBackgroundTask:bgTask]; 
];

self.timer = [NSTimer scheduledTimerWithTimeInterval:self.localInterval target:self selector:@selector(updateCoreData:) userInfo:nil repeats:YES];

方法 updateCoreData 只是调用 Core Data 类并进行必要的插入。

我已阅读有关 VoIP 和音乐播放部分的信息,但不知道哪一个最适合我的情况,也不知道如何实施。

【问题讨论】:

在您的计时器处理函数中,您可以使用 Great Central Dispatch 来完成冗长的任务。这样你就不会阻止你的事件处理程序被调用。 你成功了吗?我有同样的任务,我很努力但没有成功........你能帮帮我吗? @Xyz 是的,我成功了。为了让 NSTimers 在后台工作,我提供的代码可以工作。发生的情况是在 10 分钟左右处于非活动状态后,应用程序会关闭。为了防止这种情况,我使用了定位服务而不是 VoIP,因为它更容易实现。我在 Info.plist 文件上打开了标志,然后我做了一个计时器来启动定位服务,并每 9 分钟立即停止它。它就像一个魅力;)如果您需要示例代码,请告诉我。 是的,请给我代码....我真的需要它....我正在研究这个一个多月... @Xyz,看看我对这个问题的回答;) 【参考方案1】:

XCode 6.3.1,适用于 ios 8.3

我遇到的应用程序之间存在很大差异。使用调试器和相同的应用程序插入运行 XCode 的 Mac 时的行为。拔下电源时的行为。

在当前的 iOS 版本 8.3 中,您的应用最多被分配 180 秒的时间在后台运行,用于具有过期处理程序的有限长时间运行的任务。

无论您尝试什么,拔掉手机电源后,您的应用都会在 180 秒或更早的时间内被系统杀死。我已经进行了大量的测试和技巧来确认这一点。看我的帖子...

My NSTimer Post

这里有一个简洁的方法来告诉您的应用程序在终止之前还剩多少时间运行,请记住,您不能保证这个时间。

NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining];

if (backgroundTimeRemaining == DBL_MAX)

    NSLog(@"background time remaining = undetermined");

else

    NSLog(@"background time remaining = %0.2f sec.", backgroundTimeRemaining);

希望这对您的调查有所帮助。干杯!

【讨论】:

伙计,你是绝对正确的,现在我们将得到 180 秒,所以你的工作在 180 秒后完成,你没有办法在后台获得额外的时间,它确实在后台工作超过 180 秒在 xcode 调试器中但不在生产中【参考方案2】:

我自己想通了,对于其他有类似问题的人,我所做的是首先打开 Info.plist 文件上的位置更新标志。为此,您必须在 Xcode 4 上添加名为“Required Background Modes”的键,然后作为值选择“App registers for location updates”

我在我的 .h 文件中声明了一个计时器:

NSTimer *silenceTimer;
@property (nonatomic, retain) NSTimer *silenceTimer;

然后在 .m 文件中,我这样声明:

UIBackgroundTaskIdentifier bgTask;
UIApplication  *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^
    [app endBackgroundTask:bgTask]; 
];
self.silenceTimer = [NSTimer scheduledTimerWithTimeInterval:300 target:self
selector:@selector(startLocationServices) userInfo:nil repeats:YES];

最后,在选择器方法上,我做了如下:

-(void)startLocationServices 
    [locationManager startUpdatingLocation];
    [locationManager stopUpdatingLocation];

这将创建一个计时器,该计时器启动并在 5 分钟后立即停止位置服务。这足以让应用无限期地保持活动状态,除非您终止进程。

【讨论】:

感谢您提供的优质信息。您能告诉我如何每 15 分钟获取一次位置更新吗?我会很感激的。 @Cyril,是的,您可以使用相同的代码,但在时间间隔中不要使用 300,而是使用 900(900 秒 = 15 分钟)。这应该每 15 分钟执行一次 startLocationServices() 方法,这会激活 locationManager。对于您的情况,我建议删除行 [locationManager stopUpdatingLocation] 并在您从 locationManagerDelegate 执行代码后替换它 哇,这是对后台进程定位服务豁免的可怕滥用。我很惊讶它甚至可以工作,我原以为停止位置服务会暂停你的应用程序。在任何情况下,这都应该让您的应用被商店拒绝。 钱!我见过的最好和最简洁的解决方案 @Rajapandian 哦……不完全是。如果有充分的理由,它可以被提交。你可以继续提交它,如果它被拒绝,你可以说明你做错了什么的原因(如果它涉及这个特定的解决方案)。

以上是关于如何让我的应用在后台运行 NSTimer?的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序后台运行时,NSTimer 是不是会触发?

使NSTimer在后台运行在物理设备上

如何让我的应用在 iPhone 上后台运行?

如何让我的 android 应用程序在后台运行?

如何在 iOS 7 中超过 180 秒的后台运行 NSTimer?

有没有办法让我的 WatchKit 应用程序在后台运行?