如何在应用程序进入后台时保留NSTimer?

8

我来这里是因为我找不到解决我的问题的方法 :(

我正在制作一个简单的应用程序,需要将一些信息(例如GPS位置、精度、电池电量等)通过套接字发送到服务器。

当前的代码在应用程序在前台时运行正常。

myTimer = [NSTimer scheduledTimerWithTimeInterval: 2.0 target:self
                                                  selector: @selector(sendPosToServer:) userInfo:nil repeats: YES];
myTimer2 = [NSTimer scheduledTimerWithTimeInterval: 3.0 target:self
                                                  selector: @selector(sendBatteryToServer:) userInfo:nil repeats: YES];
myTimer3 = [NSTimer scheduledTimerWithTimeInterval: 5.0 target:self
                                                  selector: @selector(sendResToServer:) userInfo:nil repeats: YES];
myTimer4 = [NSTimer scheduledTimerWithTimeInterval: 5.0 target:self
                                                  selector: @selector(sendQResToServer:) userInfo:nil repeats: YES];
myTimer5 = [NSTimer scheduledTimerWithTimeInterval: 3.0 target:self
                                                   selector: @selector(sendPrecisionToServer:) userInfo:nil repeats: YES];

所有这些方法都已被调用。

但是当应用程序进入后台时,所有计时器都无效了...我读过iOS自动停止计时器的信息.. 我正在寻找一种在应用程序在后台时调用方法并发送数据的方法..

我需要你的帮助 :)

感谢大家!!


可能是后台重复作业的重复问题。 - Caleb
3个回答

11

您需要阅读有关如何在后台运行任务的指南:

后台执行和多任务处理

这是我为其中一个应用程序编写的applicationDidEnterBackground方法。当我将其置于后台时,它会执行一些磁盘缓存维护操作:

- (void)applicationDidEnterBackground:(UIApplication *)application {

//As we are going into the background, I want to start a background task to clean up the disk caches
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { //Check if our iOS version supports multitasking I.E iOS 4
    if ([[UIDevice currentDevice] isMultitaskingSupported]) { //Check if device supports mulitasking
        UIApplication *application = [UIApplication sharedApplication]; //Get the shared application instance

        __block UIBackgroundTaskIdentifier background_task; //Create a task object

        background_task = [application beginBackgroundTaskWithExpirationHandler: ^{
            [application endBackgroundTask:background_task]; //Tell the system that we are done with the tasks
            background_task = UIBackgroundTaskInvalid; //Set the task to be invalid
            //System will be shutting down the app at any point in time now
        }];

        //Background tasks require you to use asyncrous tasks
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //Perform your tasks that your application requires                

            //I do what i need to do here.... synchronously...                

            [application endBackgroundTask: background_task]; //End the task so the system knows that you are done with what you need to perform
            background_task = UIBackgroundTaskInvalid; //Invalidate the background_task
        });
    }
}

}


通过这部分代码,方法被调用。它可以正常工作,但我能够分发它吗? - UIChris

5
从苹果文档中得知: 实现长时间运行的后台任务,对于需要更多执行时间来实现的任务,您必须请求特定权限才能在后台运行而不被暂停。在iOS中,只有特定类型的应用程序允许在后台运行: - 在后台播放可听内容的应用程序,例如音乐播放器应用程序。 - 始终通知用户其位置的应用程序,例如导航应用程序。 - 支持互联网语音协议(VoIP)的应用程序。 - 需要下载和处理新内容的杂志架应用程序。 - 从外部配件定期接收更新的应用程序。
除非您的应用程序属于其中一类(看起来似乎不是),否则它将无法在后台运行。

我正在向我的应用程序请求GPS位置。那么像“始终将用户位置通知他们的应用程序,比如导航应用程序”这样的应用程序可以吗? - UIChris

4

iOS App Programming Guide列出了应用程序允许在后台保持活动状态的活动。如果您计划通过应用商店分发您的应用程序,则您的应用程序必须执行其中一个列出的活动。如果您只是为自己编写一些东西,您可能可以将您的功能附加到其中一个允许的活动上。


好的,我会分发它。我正在向服务器发送有关GPS数据的信息。所以我认为这很棒,对吧?“与外部附件通信”。 - UIChris
1
“外部附件”指的是连接到设备上的东西,而不是连接到网络上的服务器。因此,如果您通过蓝牙与某个GPS接收器通信来获取GPS数据,那么外部附件选项可能适用。如果您从设备自身的GPS接收器获取数据,请改用位置服务。设备会在位置发生变化时告诉您。由于无法按固定间隔更新服务器,您将不得不改变您的方法。 - Caleb
好的。我在IOS开发方面不太擅长。我理解你的意思,但我不知道如何执行它。 - UIChris
@user1147981:如果你打算将这个应用程序写成某种“车队管理”应用程序,你应该知道它不会通过审核(App Store Review Guidelines)。 - Rok Jarc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接