iOS开发之监测程序崩溃次数

作者: 夜凉听风雨 | 来源:发表于2017-06-07 11:14 被阅读358次

在写代码之前,我们先弄明白一个app运行的流程。

程序运行启动时依次调用

1.启动页先运行

2.- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

3.- (void)applicationDidBecomeActive:(UIApplication*)application

程序退到后台依次调用

1.- (void)applicationWillResignActive:(UIApplication*)application

2.- (void)applicationDidEnterBackground:(UIApplication*)application

程序从后台回到前台依次调用

1.- (void)applicationWillEnterForeground:(UIApplication*)application

2.- (void)applicationDidBecomeActive:(UIApplication*)application

程序被手动杀掉会依次调用

// 双击home键 回到正在执行的app界面走这个回调
1.- (void)applicationWillResignActive:(UIApplication*)application

// 上移app手动杀掉后走下面两个回调
2.- (void)applicationDidEnterBackground:(UIApplication*)application

3.- (void)applicationWillTerminate:(UIApplication*)application

程序崩溃闪退和在后台被系统杀掉则不会调用任何方法

分析:我们需要记录程序崩溃的次数,手动杀掉程序和程序在后台被系统回收杀掉是不能统计的。如上所述流程里,程序崩溃不会执行任何回调,但是手动杀掉程序和程序在后台被系统回收杀掉都要先让程序回到后台,走- (void)applicationDidEnterBackground:(UIApplication*)application这个回调。根据这个区别我们就可以来做一个崩溃的记录。

实现思路:在程序启动时把存储在沙盒中的崩溃标识JJ_isCrash置为YES,程序回到后台时把isCrash改为NO,程序回到前台时再把JJ_isCrash改为YES。

代码:

程序启动

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

   [self recordCrashCount];

}

程序进入后台

- (void)applicationDidEnterBackground:(UIApplication*)application {

    [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:@"JJ_isCrash"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

程序回到前台

- (void)applicationWillEnterForeground:(UIApplication *)application {

    [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"JJ_isCrash"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
// 判断和记录崩溃的次数

- (void)recordCrashCount{

    BOOL isCrash = [[[NSUserDefaults standardUserDefaults] valueForKey:@"JJ_isCrash"] boolValue];
    
    [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"JJ_isCrash"];
    
    if (isCrash == YES) {
        
        //获取到本地存储的崩溃次数
        NSNumber *crashNum = [[NSUserDefaults standardUserDefaults] valueForKey:@"JJ_crashCount"];
        
        NSInteger count =0;
        
        if (crashNum != nil) {
            
            count = [crashNum integerValue];
            
        }
        
        count++;
        
        //判断崩溃次数达到多少次时执行操作
        
        if (count >= crashCount) {
            
            NSLog(@"多次崩溃");
            
            //将本地文件崩溃次数重新置为0
            [[NSUserDefaults standardUserDefaults] setObject:@0 forKey:@"JJ_crashCount"];
            
            // 5秒后执行弹窗警告操作
            [self performSelector:@selector(showAlertAction)withObject:nil afterDelay:5];
            return;
        }
        
        //崩溃次数未达到3次则向本地存储崩溃次数
        crashNum = [NSNumber numberWithInteger:count];
        [[NSUserDefaults standardUserDefaults] setObject:crashNum forKey:@"JJ_crashCount"];
    }
}
// 弹出升级警告

- (void)showAlertAction{

UIAlertController*alert

=

[UIAlertControlleralertControllerWithTitle:@"警告"message:@"检测到软件多次异常退出,建议您尽快更新到最新版本!" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction*sure = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefaulthandler:nil];

[alert addAction:sure];

[self.window.rootViewController  presentViewController:alert animated:YES completion:nil];

}

为了方便大家直接使用,我已经将实现代码封装为一个小框架,只需使用一句代码即可调用。

github下载地址: https://github.com/jiangbin1993/JJRecordCrash

使用方法:

在appdelegate.m中导入头文件 #import "JJRecordCrash.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // 参数crashCount为崩溃多少次后执行block中的代码
    [[JJRecordCrash shareInstance] recordCrashWithCrashCount:2 handle:^{
        // 多次崩溃后执行自己想执行的代码,如:清除缓存 提示用户更新
        NSLog(@"崩溃啦");
    }];
    
    return YES;
}

注意:调试时,在程序运行中直接使用xcode重新运行程序,因为不会走- (void)applicationDidEnterBackground:(UIApplication*)application方法,所以也相当于是崩溃,同样会被记录下来。

相关文章

网友评论

  • 群星盛宴:如果是内存不足,app被杀掉会走那个didReceiveMemoryWarning方法,我把那个terminate调一遍就ok,但是如果app放入后台不操作,十分钟过后被系统回收就没法监听到了,然后就是每次打开app都会提示警告。。。此有何妙计
    夜凉听风雨:@群星盛宴 现在已经修改了 在后台的时候被杀掉将不统计崩溃次数。谢谢你的提示
  • 小邱哥:你好,有这样一种情况:
    当用户按下home键让程序进入后台时,如你所说调用- (void)applicationDidEnterBackground:(UIApplication*)application这个方法进入Background这个状态,之后程序会变为suspended状态被挂起,假设这时候系统因内存不足等原因杀掉程序时,程序是不会收到任何回调的,[[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:@"JJ_isCrash"]这行代码也无从调用,这样你是如何判断的呢。
    夜凉听风雨:已经修改为进入后台的时候记录
    夜凉听风雨:这样也会被记为程序异常崩溃
  • henry_shr:疑惑,竟然程序崩溃不调用任何会掉,你怎么记录崩溃次数的
    夜凉听风雨:@大大东 对的!
    大大东:每次启动就存储crash标志,正常结束的回调中再清空crash标志,如果下次启动存在crash标志,则认为上次发生了crash , 然后crashCount++ .....
    夜凉听风雨:兄弟 我在文章里写的很清楚的:sweat_smile:

本文标题:iOS开发之监测程序崩溃次数

本文链接:https://www.haomeiwen.com/subject/jkdnfxtx.html