区分iPhone应用程序崩溃和被杀死

时间:2011-08-11 07:32:38

标签: iphone objective-c ios crash detection

您好我打算开发一款简单的iPhone游戏。我希望能够区分真正的崩溃和用户杀死应用程序(通过双击主屏幕并长按它来杀死它)。

当有人通过多任务栏杀死应用程序时,有人可以了解一下究竟发生了什么。

3 个答案:

答案 0 :(得分:15)

如果您的应用在后台并在用户杀死时暂停,则不会收到任何通知。这占了大多数情况。

如果您的应用目前在后台正在运行(只有非常特定类别的应用可以执行此操作),则会收到applicationWillTerminate

事实上,Apple非常清楚您应该在进入后台之前保存任何相关数据。请查看this(“响应申请终止”一章):

  

即使您使用iOS SDK 4及更高版本开发应用程序,您仍然必须准备好在没有任何通知的情况下杀死您的应用程序。 用户可以使用多任务UI显式杀死应用程序。此外,如果内存受限制,系统可能会从内存中删除应用程序以腾出更多空间。 如果您的应用程序当前处于暂停状态,系统将终止您的应用程序并将其从内存中删除而不另行通知。但是,如果您的应用程序当前正在后台运行状态(换句话说,未挂起),系统将调用应用程序委托的applicationWillTerminate:方法。您的应用程序无法通过此方法请求额外的后台执行时间。

编辑:

关于“说对不起”的事情......

你可以在 next 发布时做到这一点。只需将一个密钥存储在NSUserDefaults中,并在应用程序进入后台时删除它(我希望所有这些听起来都很熟悉,否则请查看UIApplicationDelegate协议)。

当应用启动时,您检查密钥;如果它在那里,那么应用程序没有被用户关闭;如果应用程序不在那里,那么用户至少将应用程序移动到后台并且没有遇到任何突然终止...

答案 1 :(得分:7)

对于iOS6及更高版本,有一种方法可以做到这一点。 State Restoration的副作用是,当恢复期间发生崩溃或用户手动杀死应用程序时,它将删除状态。您可以利用此优势来检测用户手动终止应用程序。

来自documentation

  

请注意,当用户强制退出应用程序时,系统会自动删除应用程序的保留状态。在应用程序被杀死时删除保留的状态信息是一种安全预防措施。 (如果应用程序在启动时崩溃,系统也会删除保留状态作为类似的安全预防措施。)如果要测试应用程序恢复其状态的能力,则在调试期间不应使用多任务栏来终止应用程序。相反,使用Xcode来杀死应用程序或通过安装临时命令或手势以编程方式终止应用程序。

以下代码假定您已经有一个名为BOOL的崩溃检测_didCrashInLastSession。获取此值的方法有很多种,例如3rd party library。在您的代码中调用方法[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 :(得分:2)

您也可以通过您的设备完成此操作。 将设备连接到计算机。 运行xcode并转到管理器。 选择您的设备和设备日志。 在那里,您还可以看到您的应用或游戏的崩溃日志。