Обнаружение неожиданного закрытия моего приложения

Иногда пользователь нажимает кнопку "домой" и закрывает приложение из недавнего списка.

Я хочу предупредить пользователя с сообщением типа "This application not properly closed last time".

Как обнаружить такое неожиданное закрытие приложения? Есть ли способ сделать это? Также я хотел бы сохранить данные, заполненные пользователем.

Метод ниже работает хорошо, но, оставаясь в фоновом режиме некоторое время, и закрытие приложения не будет вызвано этим методом.

- (void)applicationWillTerminate:(UIApplication *)application

Есть ли какое-либо решение в swift 3.0?

Ответ 1

Чтобы сохранить данные, заполненные пользователем, вы должны использовать функцию func applicationDidEnterBackground(_ application: UIApplication).

Это описание функции:

//Используйте этот метод для освобождения общих ресурсов, сохранения пользовательских данных, аннулировать таймеры и хранить достаточную информацию о состоянии приложения для восстановить ваше приложение в его текущее состояние в случае его прекращения позже.         // Если ваше приложение поддерживает фоновое выполнение, этот метод вызывается вместо applicationWillTerminate: когда пользователь завершает работу.

Что касается сообщения "Это приложение не правильно закрыто в последний раз", которое вы хотите представить пользователю - неправильно показывать такое сообщение. Способ закрыть приложение - нажать главный экран и закрыть его из списка, так что это ожидаемое поведение.

Ответ 2

Пожалуйста, проверьте это, чтобы понять, как работает жизненный цикл приложения iOS - https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html

Теперь в вашем проекте найдите следующие методы для отслеживания жизненного цикла вашего приложения.

Для Objective-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 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 managed object context before the application terminates.
}

Надеюсь, что это помогло.

Ответ 3

Этот метод позволяет вашему приложению узнать, что он вот-вот будет полностью завершен и очищен от памяти. Вы должны использовать этот метод для выполнения любых окончательных задач очистки для вашего приложения, таких как освобождение общих ресурсов, сохранение пользовательских данных и недействительность таймеров. Для выполнения каких-либо задач и возврата вам потребуется около пяти секунд. Если метод не возвращается до истечения времени, система может полностью уничтожить процесс.

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

Ответ 4

Если пользователь убивает приложение вручную, когда приложение не приостановлено, applicationWillTerminate будет вызван в вашем делете приложения.

Когда пользователь просто нажимает кнопку "домой", в делегате приложения вызывается applicationDidEnterBackground.

Если вызывается applicationDidEnterBackground, а applicationWillTerminate не вероятно, приложение не было убито должным образом.

Я сказал, вероятно, потому, что нет гарантии, что applicationWillTerminate вызывается в случае приложения kill. На самом деле, если приложение приостановлено, метод не будет вызываться.

Для приложений, поддерживающих фоновое выполнение, этот метод обычно не вызывается, когда пользователь выходит из приложения, потому что приложение просто перемещается в фон в этом случае. Однако этот метод можно назвать ситуации, когда приложение работает в фоновом режиме (не приостановлено) и система по какой-то причине должна его прекратить.

источник: https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate

Сценарий, когда ручное убийство не вызвало бы вызов этого метода, - это когда пользователь нажимает кнопку "домой", а через некоторое время он дважды нажимает кнопку "домой" и убивает приложение. В этом случае iOS вызовет applicationDidEnterBackground в вашем делегате, когда пользователь нажмет кнопку "домой", а через ~ 5 секунд приложение получит статус приостановленного. Когда пользователь убьет приложение позже, его статус будет приостановлен, и метод willTerminate не будет вызван.

то же самое происходит, если приостановлено iOS убивает приложение, чтобы получить ресурсы, дающие ему статус завершенного.

Что бы я сделал, это сохранить значение времениStamp метода метода applicationDidEnterBackground, отменить его на application​Will​Enter​Foreground и в applicationWillTerminate.

Если в следующий раз, когда ваш application(_:​will​Finish​Launching​With​Options:​) будет вызван, у вас есть значение для отметки времени, сохраненной в applicationDidEnterBackground, это означает, что пользователь не вручную убил приложение (возможно), и он не вернулся после его установки в фоновом режиме.

Если пользователь убил приложение, когда приложение было приостановлено, возможно, в вашем случае это все равно будет считаться неправильным использованием приложения, и сообщение может быть отображено, чтобы весь прецедент был закрыт.

Ответ 5

Вы не должны этого делать, но если мы говорим о теории, тогда решение должно показать предупреждение всегда, кроме первого прогона.

Я бы сохранил логическое значение в UserDefaults, позвонил ему shouldShowWarning.

Все остальное может войти внутрь:

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

Внутри метода вы можете проверить, есть ли shouldShowWarning true. Если он true, покажите предупреждение. Затем установите значение true.

Теперь, если приложение завершено и вы вернетесь назад, появится предупреждение.

Если существует какой-то сценарий, когда вы завершаете приложение из кода (что очень нестандартно), просто установите shouldShowWarning на false, чтобы отключить предупреждение при перезапуске приложения.

Ответ 6

Вы можете использовать метод AppDelegate Method resignActive для сохранения данных, когда пользователь отправляет приложение в фоновый режим. И сохраните логическое значение true в NSUserDefaults, если оно запускается из метода didFinishLaunching и проверяет эти логические и сохраненные данные для вычисления в методе didBecomeActive. Используя данные и логическое значение, вы можете показать предупреждение и reset оба значения.

Ответ 8

В делетете приложения вы можете проверить разные события. Проверьте метод applicationWillResignActive или ApplicationDidEnterBackground.

Соответствующее место будет зависеть от вашего использования.