简体   繁体   English

让iOS应用程序在前台运行

[英]Keep an iOS app running in foreground

I would like to know if there's a way to keep an app running in foreground, during a specific interval time. 我想知道是否有办法让应用程序在特定的间隔时间内保持在前台运行。

I have a thread running exactly during 3 minutes and I need that the user cannot leave the app. 我有一个线程正好在3分钟内运行,我需要用户不能离开应用程序。 If such a thing is not possible I'm going to ask another question. 如果这样的事情不可能,我会问另一个问题。

I could let that the user set the app in background mode because I use the applicationDidEnterBackground:(UIApplication *)application method to save the data I need but if the user clicks the power button, how could I save the data? 我可以让用户在后台模式下设置应用程序,因为我使用applicationDidEnterBackground:(UIApplication *)application方法来保存我需要的数据,但如果用户单击电源按钮,我该如何保存数据?

The applicationWillTerminate:(UIApplication *)application would be called? applicationWillTerminate:(UIApplication *)application将被调用? Is there any solution? 有什么解决方案吗?

You might want to look into beginBackgroundTaskWithExpirationHandler , which lets your app request additional processing time to complete tasks when your app is backgrounded. 您可能希望查看beginBackgroundTaskWithExpirationHandler ,它可以让您的应用请求额外的处理时间来完成应用程序后台运行时的任务。

That said, what you're looking to do isn't advisable. 也就是说,你想做的事情是不可取的。 You should make sure your app can recover from your three minute task in case of unexpected termination or failure. 您应该确保您的应用可以在意外终止或失败的情况下从您的三分钟任务中恢复。 For example, your app could crash unexpectedly or terminate due to low memory - in these cases, you won't get any callbacks to applicationWillTerminate or applicationDidEnterBackground . 例如,您的应用程序可能会意外崩溃或因内存不足而终止 - 在这些情况下,您将无法获得对applicationWillTerminateapplicationDidEnterBackground任何回调。

So my recommendation would be to look at using iOS's background task support to have your save continue in the background if the user leaves the app, but also ensure that in the event your app be terminated by the system without warning your task is recoverable / can safely be rewound. 因此,我建议使用iOS的后台任务支持,以便在用户离开应用程序时在后台继续保存,同时还要确保在系统终止您的应用程序而不发出警告时您的任务可以恢复/可以安全地倒回来。

You need to use beginBackgroundTaskWithExpirationHandler to handle your process alive. 您需要使用beginBackgroundTaskWithExpirationHandler来处理您的进程。 use this code. 使用此代码。

Here I called this method from applicationDidEnterBackground:(UIApplication *)application to store the data in SQlite even the application enter background or UIApplicationStateInactive (press power button). 这里我从applicationDidEnterBackground调用此方法:( UIApplication *)应用程序将数据存储在SQlite中,即使应用程序输入后台或UIApplicationStateInactive(按下电源按钮)。 Saving process will continue for 10 mins as per the IOS standard if application.backgroundTimeRemaining comes to 0 I will post one local notification to bring up my application to foreground to keep my process alive. 如果application.backgroundTimeRemaining变为0,保存过程将按照IOS标准继续保持10分钟。我将发布一个本地通知,将我的应用程序调到前台以保持我的进程活着。 use this code and customize your process. 使用此代码并自定义您的过程。

-(void)handleBackgroundSavingingProcess:(UIApplication *)application
    {
        NSLog(@"background task remaining time before background %f",application.backgroundTimeRemaining);

        if ((([application applicationState] == UIApplicationStateBackground) || ([application applicationState] == UIApplicationStateInactive)) && [application respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
  {


     self.bgTaskId = [application beginBackgroundTaskWithExpirationHandler:^{
     // Synchronize the cleanup call on the main thread in case
     // the task actually finishes at around the same time.
                NSLog(@"background task remaining time in expiration handler %f",application.backgroundTimeRemaining);

                dispatch_queue_t concurrentQueue;
                if([[[UIDevice currentDevice] systemVersion] doubleValue] >= 5.0)
                    concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0UL);
                else
                    concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);

                if (concurrentQueue == nil)
                    return;

                dispatch_async(concurrentQueue, ^{

                    if (self.bgTaskId != UIBackgroundTaskInvalid){
                        NSLog(@"background task remaining time in dispatch queue %f",application.backgroundTimeRemaining);
                        NSLog(@" Downloading status %d",self.isDownloadingInComplete);
                        if(self.isDownloadingInComplete)
                        {
                            [application presentLocalNotificationNow:localNotification];
                            NSLog(@"Local notification fired.");
                        }
                        [DataManager managedObjectContext] save:nil];
                        [application endBackgroundTask:self.bgTaskId];
                        self.bgTaskId = UIBackgroundTaskInvalid;
                        NSLog(@"Initialization invalid.");
                    }
                });
            }];
        }

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM