xcode 保持 iOS 应用在前台运行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15335083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 02:56:44  来源:igfitidea点击:

Keep an iOS app running in foreground

iphoneiosxcodebackgroundforeground

提问by user1708257

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. If such a thing is not possible I'm going to ask another question.

我有一个线程正好在 3 分钟内运行,我需要用户不能离开应用程序。如果这样的事情是不可能的,我会问另一个问题。

I could let that the user set the app in background mode because I use the applicationDidEnterBackground:(UIApplication *)applicationmethod 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 *)applicationwould be called? Is there any solution?

applicationWillTerminate:(UIApplication *)application会叫什么名字?有什么解决办法吗?

回答by lxt

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 applicationWillTerminateor applicationDidEnterBackground.

也就是说,您要做的事情是不可取的。您应该确保您的应用程序可以在意外终止或失败的情况下从您的三分钟任务中恢复。例如,您的应用程序可能会因内存不足而意外崩溃或终止 - 在这些情况下,您将不会收到applicationWillTerminate或 的任何回调applicationDidEnterBackground

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 的后台任务支持,如果用户离开应用程序,让你的保存在后台继续,但也要确保你的应用程序在没有警告的情况下被系统终止,你的任务是可恢复的/可以安全地被倒带。

回答by Ganapathy

You need to use beginBackgroundTaskWithExpirationHandlerto handle your process alive. use this code.

你需要使用beginBackgroundTaskWithExpirationHandler来处理你的进程。使用此代码。

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). 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. use this code and customize your process.

在这里,我从 applicationDidEnterBackground:(UIApplication *)application 调用了这个方法,以将数据存储在 SQlite 中,即使应用程序进入后台或 UIApplicationStateInactive(按电源按钮)。如果 application.backgroundTimeRemaining 为 0,保存过程将按照 IOS 标准持续 10 分钟,我将发布一个本地通知以将我的应用程序调至前台,以保持我的进程处于活动状态。使用此代码并自定义您的流程。

-(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.");
                    }
                });
            }];
        }

    }