2016-11-30 221 views
10

有时用户按下主页按钮并关闭最近列表中的应用程序。检测我的应用程序的意外关闭

我想通过诸如“This application not properly closed last time”之类的消息来警告用户。

如何检测这种意外关闭应用程序?有什么办法可以做到吗? 另外我想保存用户填写的数据。

下面的方法工作良好,但在留在后台一段时间后关闭应用程序将不会被调用到此方法。

- (void)applicationWillTerminate:(UIApplication *)application 

swift 3.0有没有解决方案?

+8

没有意外关闭应用程序这样的事情。在后台应用程序被杀害是正常的。你的应用应该正确处理这个。向用户显示这样的消息是没有意义的。 – rmaddy

+1

'我想告诉用户一个消息,比如“这个应用程序没有上次正确关闭”。 - 这是违反Apple的做法......使用最近的列表**关闭应用程序是**正确的方式关闭iOS上的应用程序 –

+0

@MihaiFratu是的..我同意你的看法,但也有关闭应用程序的另一种可能性..我们如何管理该应用程序 – Saranjith

回答

-3

在应用程序委托中,您可以检查不同的事件。检查applicationWillResignActive方法或ApplicationDidEnterBackground。

适当的位置将取决于您的用例。

+0

我同意你的意见。但我怎么知道应用程序已关闭或不关闭 – Saranjith

+0

通常,当用户按下主页键时,最前面的应用程序将移至背景,然后移至暂停状态。它不会马上关闭。我的猜测是,您每次应用程序转到后台时都试图保存信息。在这种情况下,您可以在应用程序中添加您的保存逻辑WillResignActive。此外,为了下一次提醒用户,您可以将变量保存在NSUserDefaults中,检查该值并在需要时提醒用户。 – TheAppMentor

-1

此方法可让您的应用程序知道它即将被终止并从内存中完全清除。您应该使用此方法为您的应用程序执行任何最终清理任务,例如释放共享资源,保存用户数据以及使定时器无效。您执行此方法大约需要五秒钟来执行任何任务并返回。如果该方法在时间到期之前没有返回,系统可能会完全终止该过程。

-(void) applicationWillTerminate:(UIApplication *)application{ } 
+0

它运行良好,但在后台停留更多时间并从最近的菜单中关闭后不会调用此方法 – Saranjith

-2

可以使用的AppDelegate方法resignActive保存数据时,用户发送应用背景。如果从didFinishLaunching方法启动并在方法didBecomeActive中检查此布尔值和保存的数据以进行计算,则在NSUserDefaults中保存一个布尔值true。使用数据和布尔值可以显示警报并重置这两个值。

4

要保存用户填写的数据,应该使用func applicationDidEnterBackground(_ application: UIApplication)函数。

这是功能描述:

//使用这个方法来释放共享资源,保存用户数据, 无效定时器和足够的应用程序状态信息存储到 您的应用程序恢复到其当前状态它会在稍后终止 。 //如果您的应用程序支持后台执行,则调用此方法而不是applicationWillTerminate:当用户 退出时。

至于“上次没有正确关闭此应用程序”消息,您想要显示用户 - 显示此类消息是错误的。 关闭应用程序的方法是按主屏幕并从列表中关闭它,所以这是预期的行为。

+4

这应该被接受,因为它是正确的答案。另外,它表明*你不应该做这样的对话*。基本上,iOS上关于应用程序关闭的原因是“这不关你的事”。无论是用户的结果(从任务管理器刷卡)还是系统,都需要“准备好”终止。尽管整个生命周期比经常更复杂。请参阅https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW3 – Gero

+1

哦,一个小的补充:Don不要只依赖项目模板的应用程序委托中的评论。那些可能会过时,或者至少会过分简化事情。我链接的完整文档以及正确的方法文档更清楚地解释了这一点。特别是'applicationWillTerminate'方法中的注释有点令人误解(从我们在iOS上进行后台执行和多任务处理之前的日子来看,它基本上是一样的)。 – Gero

0

请检查该了解的iOS应用程序生命周期是如何工作 - https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html

现在,在你的项目中发现这下面的方法来跟踪应用程序的生命周期过程。

对于目标C

- (void)applicationWillResignActive:(UIApplication *)application{ 
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application{ 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
} 

- (void)applicationWillTerminate:(UIApplication *)application{ 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
    // Saves changes in the application's managed object context before the application terminates. 
} 

为SWIFT(3.0)

func applicationWillResignActive(_ application: UIApplication) {   
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
} 

func applicationDidEnterBackground(_ application: UIApplication) { 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
} 

func applicationWillTerminate(_ application: UIApplication) { 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
    // Saves changes in the application's managed object context before the application terminates. 
} 

希望这有助于。

-1

如果用户在应用程序未挂起时手动杀死应用程序,将在您的应用程序委托中调用applicationWillTerminate

当用户只需按主页按钮,applicationDidEnterBackground在您的应用程序委托中被调用。

如果applicationDidEnterBackground被调用,而applicationWillTerminate可能应用程序没有正确杀害。

我说可能是因为没有保证,applicationWillTerminate被称为应用程序杀死的情况下。事实上,如果应用程序被暂停,该方法将不会被调用。

对于支持后台执行的应用程序,这种方法通常是当用户退出该应用,因为该应用简单地移动到 在这种情况下,背景 不被调用。但是,可能会在 应用程序在后台运行(未暂停) 且系统因某种原因需要终止该应用程序的情况下调用此方法。

来源:https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate

时手动杀不会造成这种方法被称为是当用户按下home键,并在一段时间后,他按两次home键,并终止该应用场景。在这种情况下,当用户按下主页按钮时,iOS会在您的委托中调用applicationDidEnterBackground,并且在约5秒后,应用程序将获得挂起状态。当用户稍后杀死应用时,其状态将被暂停,并且willTerminate方法将不会被调用。

同样的情况发生时,如果暂停iOS杀死应用程序以获取资源给予终止状态。

我会做的是坚持applicationDidEnterBackground方法调用的时间戳,取消它在application​Will​Enter​ForegroundapplicationWillTerminate

如果下一次你application(_:​will​Finish​Launching​With​Options:​)被调用你有保存在applicationDidEnterBackground时间戳值则意味着用户没有手动终止应用程序(可能),他把它在后台后没有回来。

如果用户在应用程序被暂停期间杀了应用程序,也许在您的情况下,它仍然会被视为滥用应用程序,并且可以显示该消息,以便涵盖所有用例。

+0

这将是很好的评论反对票。 –

-1

你不应该这样做,但如果我们谈论理论,那么解决方案是显示警告总是,除了第一次运行。

我会在UserDefaults中保存一个布尔值,我们称之为shouldShowWarning

事都可以往里走:

UIApplicationDelegate.application(_:​did​Finish​Launching​With​Options:​) 

里面的方法,你可以检查shouldShowWarning是否true。如果是true,请显示警告。 然后将值设置为true

现在,如果应用程序终止并返回,则会显示警报。

如果在某些情况下当您从代码(非常标准)终止应用程序时,只需将shouldShowWarning设置为false即可在应用程序重新启动时禁用警告。