Различают падение приложения iPhone и его гибель - PullRequest
8 голосов
/ 11 августа 2011

Здравствуйте, я планирую разработать простую игру для iPhone. Я хотел бы иметь возможность различать подлинный сбой и пользователь, убивающий приложение (дважды нажав домашний экран и нажав и удерживая его, чтобы убить его).

Может кто-нибудь пролить свет на то, что именно происходит, когда пользователь убивает приложение через панель многозадачности.

Ответы [ 3 ]

15 голосов
/ 11 августа 2011

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

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

Действительно, Apple очень четко говорит о том, что вам следует сохранить любые соответствующие данные перед входом в фоновый режим.Взгляните на this (глава «Ответ на завершение приложения»):

Даже если вы разрабатываете свое приложение с использованием iOS SDK 4 и более поздних версий, вы все равно должны быть готовы кПриложение должно быть убито без какого-либо уведомления. Пользователь может явно уничтожать приложения, используя многозадачный интерфейс. Кроме того, если память становится ограниченной, система может удалить приложения из памяти, чтобы освободить место. Если ваше приложение в настоящий момент приостановлено, система убивает ваше приложение и удаляет его из памяти без какого-либо уведомления .Однако, если ваше приложение в данный момент работает в фоновом состоянии (другими словами, не приостановлено), система вызывает applicationWillTerminate: метод вашего делегата приложения.Ваше приложение не может запросить дополнительное время фонового выполнения с помощью этого метода.

РЕДАКТИРОВАТЬ:

о "извините" вещь ...

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

при запуске приложения вы проверяетеключ;если он есть, то приложение не было закрыто пользователем;если приложения там нет, то пользователь, по крайней мере, переместил приложение в фоновый режим и не столкнулся с внезапным завершением ...

7 голосов
/ 18 июля 2013

Для iOS6 и новее есть способ сделать это.Побочным эффектом State Restoration является то, что он удалит состояние, если во время восстановления произойдет сбой или пользователь вручную убьет приложение.Вы можете использовать это в своих интересах, чтобы обнаружить пользователя, убивающего приложение вручную.

Из документации :

Имейте в виду, что система автоматически удаляет сохраненное состояние приложения, когда пользователь принудительно покидает приложение.Удаление сохраненной информации о состоянии, когда приложение убито, является мерой безопасности.(Система также удаляет сохраненное состояние, если приложение вылетает во время запуска в качестве аналогичной меры предосторожности.) Если вы хотите проверить способность вашего приложения восстановить его состояние, вам не следует использовать панель многозадачности, чтобы убить приложение во время отладки.Вместо этого используйте XCode, чтобы убить приложение или убить приложение программно, установив временную команду или жест для вызова exit по требованию.

В следующем коде предполагается, что у вас уже есть BOOL для обнаружения сбояназывается _didCrashInLastSession.Есть разные подходы для получения этого значения, такие как сторонняя библиотека .В своем коде вызовите метод [self getLaunchType], чтобы увидеть, с каким типом запуска вы имеете дело, и действовать соответствующим образом.Поместите в свой AppDelegate.m следующее:

typedef NS_ENUM(NSInteger, LaunchType) {
    LaunchTypeUnknown,
    LaunchTypeNewInstall,
    LaunchTypeNormalLaunch,
    LaunchTypeCrashedLastSession,
    LaunchTypeUserManualQuit,
};

static BOOL hadStateToRestore = NO;
static NSString * const kAppHasEverRunKey = @"appHasEverRun";

- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
    // Called when going into the background
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAppHasEverRunKey];
    [[NSUserDefaults standardUserDefaults] synchronize];

    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
    // Called on start up
    hadStateToRestore = YES;
    return YES;
}

- (LaunchType)getLaunchType
{
    if (_didCrashInLastSession) {
        return LaunchTypeCrashedLastSession;
    }

    if (![[NSUserDefaults standardUserDefaults] boolForKey:kAppHasEverRunKey]) {
        return LaunchTypeNewInstall;
    }

    if (!hadStateToRestore) {
        return LaunchTypeUserManualQuit;
    }

    return LaunchTypeNormalLaunch;
}

Обновление : по крайней мере один сторонний SDK ломает эту технику: Urban Airship.

2 голосов
/ 11 августа 2011

Вы также можете сделать это через ваше устройство. Подключите ваше устройство к вашей машине. Запустите xcode и перейдите в органайзер. Там выберите ваше устройство и журналы устройства. Там вы также можете увидеть журналы сбоев вашего приложения или игры.

...