美文网首页
iOS杀死程序后调用网络请求和数据库操作

iOS杀死程序后调用网络请求和数据库操作

作者: 原味丿丿咖啡Vitas | 来源:发表于2020-07-07 16:02 被阅读0次

    项目中碰到一个需求,就是在退出控制器后进行埋点操作,正常情况我们在controller的delloc中执行埋点的网络请求就OK了,但是还有一种情况,如果用户杀死程序,是不会走delloc方法的。这时候需要监听杀死程序的通知,这里贴下最终代码,想看思路的请往后看。

    - (void)viewDidLoad {
        [super viewDidLoad];
        //监听通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:@"UIApplicationWillTerminateNotification" object:nil];
    }
    
    //程序被杀死
    - (void)applicationWillTerminate:(UIApplication *)application {
        //进行埋点操作
        [self uploadData];
        [NSThread sleepForTimeInterval:5];
        NSLog(@"程序被杀死");
    }
    
    
    • 一开始想着直接在监听到杀死App后直接埋点,所以在控制器中加入了如下代码:
    - (void)viewDidLoad {
        [super viewDidLoad];
        //监听通知
       [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:@"UIApplicationWillTerminateNotification" object:nil];
    }
    
    
    //程序被杀死
    - (void)applicationWillTerminate:(UIApplication *)application {
        //进行埋点操作
        [self uploadData];
        NSLog(@"程序被杀死");
    }
    
    
    • 本以为这样就大功告成了,谁知道埋点没生效,打断点发现杀死程序后网络请求并没有走完。了解到系统执行完回调applicationWillTerminate:后,在那一次主线程 runloop 结束, 系统就会杀死应用进程, 所以后续的网络请求,磁盘操作,异步代码 等等就都没执行了。在网上查找资料主要有两种方法:1.说要把这里的网络请求改成在主线程。2.另外一种方法是阻塞主线程,这里贴下该作者的代码地址https://www.jianshu.com/p/5142ebe74c6d
    • 看了这两种方法,觉得第一种方法网络请求改主线程太过麻烦,因为我这里的埋点有好几个,所以选择第二种方法,但觉得作者的做法也太麻烦了,按照思路,无非就是阻塞主线程,让埋点的网络请求走完才让主线程结束,这时候我突然灵机一动:我们启动APP进入欢迎界面一般就需要沉睡几秒才进入主界面:
    [NSThread sleepForTimeInterval:3];
    

    是否可以利用这个方法实现我们的需求?于是我在监听到App被杀死,进行埋点操作后加入上面的代码。

    - (void)viewDidLoad {
        [super viewDidLoad];
        //监听通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:@"UIApplicationWillTerminateNotification" object:nil];
    }
    
    //程序被杀死
    - (void)applicationWillTerminate:(UIApplication *)application {
        //进行埋点操作
        [self uploadData];
        [NSThread sleepForTimeInterval:5];
        NSLog(@"程序被杀死");
    }
    
    

    发现此方法确实可行,而且简单,但有个缺点就是如果网络请求慢的话,有可能埋点会失败。大家可以尝试用NSTimer阻塞,然后埋点网络请求完后invalidate。

    相关文章

      网友评论

          本文标题:iOS杀死程序后调用网络请求和数据库操作

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