如我们所知,iOS 10.3里面添加了一个新的方法 setAlternateIconName:completionHandler:,用来更换App的icon,但是此方法有个比较烦人的地方,每次更换icon都会弹出一个alertController,如果能只换icon,不弹这个框该多好??
想要实现这个目的大概有这么几个思路:
-
由于一个UIViewController present一个ViewController后就不能再present了,所以我们可以先present一个阻止setAlternateIconName:completionHandler方法弹出alert。大概代码如下:
[[UIApplication sharedApplication] setAlternateIconName:@"xxx" completionHandler:NULL]; UIViewController *tempViewController = [[UIViewController alloc] init]; tempViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; tempViewController.view.backgroundColor = [UIColor clearColor]; [self presentViewController:tempViewController animated:NO completion:^{ [self dismissViewControllerAnimated:NO completion:NULL]; }];
经测试在快速调用的时候会有崩溃现象,控制台也会打印出一些警告信息,有兴趣的同学可以自己去改进
设置icon时弹出的alert的title和message都为nil,我们可以利用运行时方法method_exchangeImplementations修改presentViewController:animated:completion:方法的实现,在检测到弹出的viewController是alertController且title和message都为nil时,什么都不做。记得在调用method_exchangeImplementations之前保存presentViewController:animated:completion:方法的originalMethod和originalIMP,以便在调用setAlternateIconName:completionHandler结束之后通过method_setImplementation方法重置presentViewController:animated:completion:的实现,这儿就不给具体的代码了。
-
有没有更简单一点的方案呢,有的
- (void)lc_setAlternateIconName:(NSString*)iconName { //anti apple private method call analyse if ([[UIApplication sharedApplication] respondsToSelector:@selector(supportsAlternateIcons)] && [[UIApplication sharedApplication] supportsAlternateIcons]) { NSMutableString *selectorString = [[NSMutableString alloc] initWithCapacity:40]; [selectorString appendString:@"_setAlternate"]; [selectorString appendString:@"IconName:"]; [selectorString appendString:@"completionHandler:"]; SEL selector = NSSelectorFromString(selectorString); IMP imp = [[UIApplication sharedApplication] methodForSelector:selector]; void (*func)(id, SEL, id, id) = (void *)imp; if (func) { func([UIApplication sharedApplication], selector, iconName, ^(NSError * _Nullable error) {}); } } }