登录 立即注册
金钱:

Code4App-iOS开发-iOS 开源代码库-iOS代码实例搜索-iOS特效示例-iOS代码例子下载-Code4App.com

iOS 前台重启应用和清除角标的问题

[复制链接]
来自: wsl2ls 分类: iOS精品源码 上传时间: 2019-1-2 09:39:37
Tag:

项目介绍:

问:应用启动时是否会执行 - (void)applicationWillEnterForeground:(UIApplication *)application ?
答:不会 ? 你确定?那看一哈下面的情况。示例Github地址

前台时重启应用调用了applicationWillEnterForeground:

已知条件:

   应用在退到后台时,会给应用加上一层毛玻璃效果,防止iOS系统自动对应用当前界面进行截屏处理时获取到用户的某些隐私,提高安全性;同时也会在退到后台时,重置应用的消息角标。


//当应用启动载入完成后执行,也就是系统启动屏加载完成后执行
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSLog(@" 应用启动完成 ");
    //延长系统启动屏展示的时长
    [NSThread sleepForTimeInterval:2];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
    
    //注册通知
    UNUserNotificationCenter * center  = [UNUserNotificationCenter currentNotificationCenter];
    //设置代理,用于检测点击方法
    center.delegate = self;
    //申请权限
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge + UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            NSLog(@"用户同意开启通知");
        }
    }];
    return YES;
}

//当应用即将进入非活动状态时执行
- (void)applicationWillResignActive:(UIApplication *)application {
    NSLog(@" 即将进入非活动状态 ");
}

//当应用进入后台时执行  或者应用在前台时被强制关闭时执行
- (void)applicationDidEnterBackground:(UIApplication *)application {
    //给处于后台的应用添加毛玻璃效果
    if (_effectView == nil) {
        UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
        _effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
        _effectView.frame = CGRectMake(0, 0, self.window.frame.size.width, self.window.frame.size.height);
    }
    [self.window addSubview:_effectView];
    
    // 实现如下代码,才能使程序处于后台时被杀死后调用applicationWillTerminate:方法
     [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(){}];
  
    //重置应用的角标
    [self resetApplicationIconBadgeNumber];
    NSLog(@" 进入后台 ");
}

//当应用即将从后台进入前台时执行,重新启动应用时并不执行,除了此demo演示的特殊情况
- (void)applicationWillEnterForeground:(UIApplication *)application {
  
    if (_effectView != nil) {
        [_effectView removeFromSuperview];
        _effectView = nil;
    }
    
    //弹窗
//   SL_ULog(@"执行了 applicationWillEnterForeground ");
    NSLog(@" 即将从后台进入前台 ");
}

//当应用进入活动状态时执行
- (void)applicationDidBecomeActive:(UIApplication *)application {
    if (_effectView != nil) {
        [_effectView removeFromSuperview];
        _effectView = nil;
    }
    NSLog(@" 进入活动状态 ");
}

//应用被杀死时调用
- (void)applicationWillTerminate:(UIApplication *)application {
    NSLog(@" 应用被杀死了 ");
}

#pragma mark - iOS10 收到通知(本地和远端) UNUserNotificationCenterDelegate

//当APP处于前台的时候收到通知的事件
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    // 系统要求执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
    completionHandler(UNNotificationPresentationOptionBadge|
                      UNNotificationPresentationOptionSound|
                      UNNotificationPresentationOptionAlert);
}

//这个方法是为了清除应用的角标,同时又不清除之前发送的通知内容
- (void)resetApplicationIconBadgeNumber {
 //使用这个方法清除角标,如果置为0的话会把之前收到的通知内容都清空;置为-1的话,不但能保留以前的通知内容,还有角标消失动画,iOS10之前这样设置是没有作用的 ,iOS10之后才有效果 。
    [UIApplication sharedApplication].applicationIconBadgeNumber = -1;
    
//这个发送本地通知的操作是为了解决在iOS10之前清除角标的同时可以保留通知内容的问题
   //这个进入后台时清除角标的操作会造成:应用在前台时被强制关闭后,立马重启应用后会调用方法applicationWillEnterForeground:,正常情况下重新启动应用时并不执行它.
//    UILocalNotification *clearEpisodeNotification = [[UILocalNotification alloc] init];
//    clearEpisodeNotification.applicationIconBadgeNumber = -1;
//    [[UIApplication sharedApplication] scheduleLocalNotification:clearEpisodeNotification];
}

问题描述:

   当应用在前台时,手动强制重启应用后,发现没有正常的加载启动屏,加载的启动屏是退入后台时的应用截屏。

前台时重启应用出现的问题展示

调试分析

   经过不断调试之后,发现:在前台时重启应用后,调用 application: didFinishLaunchingWithOptions: 方法之后,还调用了applicationWillEnterForeground: ???? “这操作不合理呀!应用启动时应该不会执行 applicationWillEnterForeground 方法呀!” 如下示意图,我加了个弹窗验证:

前台时重启应用调用了applicationWillEnterForeground:

   为什么在前台时重启应用会执行 applicationWillEnterForeground ?通过删除排除法,找到了导致此问题的代码,如下,这段代码是退入后台时清除角标的操作。如果不在应用退入后台时执行下面的清除角标操作,就是正常的。


//当应用进入后台时执行  或者应用在前台时被强制关闭时执行
- (void)applicationDidEnterBackground:(UIApplication *)application {
//这个发送本地通知的操作是为了解决在iOS10之前清除角标的同时可以保留通知内容的问题
 //这个清除角标的操作只在进入后台时执行才会造成:应用在前台时被强制关闭后,立马重启应用后会调用方法applicationWillEnterForeground:,正常情况下重新启动应用时并不执行它;
    UILocalNotification *clearEpisodeNotification = [[UILocalNotification alloc] init];
    clearEpisodeNotification.applicationIconBadgeNumber = -1;
    [[UIApplication sharedApplication] scheduleLocalNotification:clearEpisodeNotification];
}

   这时有人肯定会疑惑为啥不用[UIApplication sharedApplication].applicationIconBadgeNumber = 0 ?

   因为把应用角标值置为0的话会把之前收到的通知栏内的通知内容都清空,这样显然是不合理的;如果置为-1的话,不但能保留以前的通知内容,还有角标消失动画,iOS10之前这样设置是没有作用的 ,iOS10之后才有效果 ;所以iOS10之前只能通过上述代码来实现。

解决问题

   方案一 : 把上述清除角标的代码放在应用进入前台时执行的方法 applicationDidBecomeActive: 里面,这样的话就是看不到角标消失的过程。

   方案二:通过 [UIApplication sharedApplication].applicationIconBadgeNumber = -1 来清除角标。


- (void)applicationDidEnterBackground:(UIApplication *)application {
   //使用这个方法清除角标,如果置为0的话会把之前收到的通知内容都清空;置为-1的话,不但能保留以前的通知内容,还有角标消失动画,iOS10之前这样设置是没有作用的 ,iOS10之后才有效果 。
    [UIApplication sharedApplication].applicationIconBadgeNumber = -1;
}

问题解决后

虽然问题解决了,但是为什么 调试分析 步骤中的问题代码会导致在前台时重启应用会执行 applicationWillEnterForeground:? 是系统的Bug ? 如果小伙伴有谁知道的话,欢迎底部留言交流

如果需要跟我交流的话:

※ Github: https://github.com/wsl2ls
※ 简书:https://www.jianshu.com/u/e15d1f644bea
※ 微信公众号:iOS2679114653
※ QQ:1685527540

相关源码推荐:

我来说两句
*滑动验证:
所有评论(5)
天天bug 2019-1-2 10:27:47
不错不错,楼主辛苦了。。。
回复
Wsdtg 2019-1-2 10:28:01
帮帮顶顶!!
回复
乱世佳人520 2019-1-2 10:28:31
code4app好的内容真的很多~赞
回复
知新1990 2019-1-2 10:28:43
感谢分享,楼主V5~
回复
hellokenken 2019-1-2 10:29:08
膜拜大神~
回复
pp美景 2019-1-2 10:29:42
不错不错,楼主辛苦了。。。
回复
code4app热心网友 2019-1-3 11:27:44
楼主威武啊,Code4App有你更给力!
回复
code4app热心网友 2019-1-3 11:28:44
很给力,Code4App有你更精彩!
回复
zhentivip 2019-1-3 23:13:37
正需要啊,感谢楼主无私分享!
回复
提取码:  下载次数:4 状态:已购或VIP 售价:0(原价:15)金钱 下载权限:初级码农 
941 0 4
联系我们
首页/微信公众账号投稿

帖子代码编辑/版权问题

QQ:435399051,742864542

如何获得代码达人称号?

代码贡献英雄榜
用户名 下载数
通过邮件订阅最新 Code4App 信息
上一条 /4 下一条
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|Github|申请友链|手机版|Code4App ( 粤ICP备15117877号-1 )

快速回复 返回顶部 返回列表