ios 自动切换app icon风波

1.把PNG格式的图片放在文件目录里,要求,格式为PNG,120*120像素。

2.配置info.plist,Icon files (iOS 5). CFBundleAlternateIcons newicon
截屏2025-02-12 15.08.10.png

3.上代码:

在指定的时间更新图标。

-(void)changeAppicon
{
    BOOL isIconChanged = [[NSUserDefaults standardUserDefaults]objectForKey:@"logo2"];
    if (!isIconChanged) {
        //2025-02-01 00:00:00
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]];

        NSDate *targetDate = [formatter dateFromString:@"2025-02-01 00:00:00"];
        NSDate *currentDate = [NSDate date];
        NSTimeInterval timeInterval = [targetDate timeIntervalSinceDate:currentDate];
        if(timeInterval <= 0 ){
            // 方法替换拦截更换icon时系统弹出的alert
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                Method presetnM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
                Method swizzlingM = class_getInstanceMethod(self.class, @selector(hy_presentViewController:animated:completion:));
                method_exchangeImplementations(presetnM,swizzlingM);
            });
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                // 在这里添加需要延迟执行的代码
                [[UIApplication sharedApplication]setAlternateIconName:@"newicon" completionHandler:^(NSError * _Nullable error) {
                    if (error){
                        NSLog(@"失败了:%@",error);
                    }else{
                        [[NSUserDefaults standardUserDefaults]setObject:@"1" forKey:@"logo2"];
                        NSLog(@"成功了");
                    }
                }];
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    // 方法交换用完了,要交换回来。
                    Method presetnM = class_getInstanceMethod(self.class, @selector(presentViewController:animated:completion:));
                    Method swizzlingM = class_getInstanceMethod(self.class, @selector(hy_presentViewController:animated:completion:));
                    method_exchangeImplementations(swizzlingM,presetnM);
                });
            });
        }
    }
}

交换的方法:

-(void)hy_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if ([viewControllerToPresent isKindOfClass:[UIAlertController class]]) {
            NSLog(@"title : %@",((UIAlertController *)viewControllerToPresent).title);
            NSLog(@"message : %@",((UIAlertController *)viewControllerToPresent).message);
            
            UIAlertController *alertController = (UIAlertController *)viewControllerToPresent;
            if (alertController.title == nil && alertController.message == nil) {
                return;
            } else {
                [self hy_presentViewController:viewControllerToPresent animated:flag completion:completion];
                return;
            }
        }
    [self hy_presentViewController:viewControllerToPresent animated:flag completion:completion];
}

**
1.这个方法有致命的缺点,会导致app闪退。所以拦截系统的提示之后,一定要交换回来,否则后患无穷。
2.如果你有更好的方式,可以在评论区探讨。
**

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容