ios平台alternate icon配置注意事项

ios平台alternate icon配置注意事项

ios支持动态更换用户的appicon,要实现这个功能,一共需要进行三步操作:

  1. 将icon文件导入xcode项目中,icon文件需要png格式
  2. 在info.plist中配置可更换的icon列表
  3. 增加更换icon代码

当然实际上按apple的要求,还需要一个让用户主动选择使用哪一个icon的界面,由于这是另一个功能,这里就不展开写了。
详细的接入方式在很多文章中都已经有分享了,所以我本文中也不会将具体步骤展开细讲,重点会放在接入过程中所遇到的坑点。下面按照这三个步骤分类逐项说明。

第一步,将icon文件导入xcode项目

这一步操作比较简单,正常将图片文件引入xcode项目中即可,需要注意的是,icon的图片文件不能放在Asset.xcassets里。
但即使看起来简单,但仍然会遇到坑。
理论上来说,icon文件的文件名和尺寸都没有要求,但在实际操作中会遇到下面几个问题:

问题1:提审时因为缺少关键尺寸导致提审失败

  • 遇到的问题
    我所在的项目在提审时就遇到过下面这样的问题,结果导致提审失败,其原因是缺少了一些关键的icon尺寸。

    ITMS-90892: Missing recommended icon - The bundle does not contain an alternate app icon for iPad of exactly ‘152x152’ pixels, in .png format for iOS versions >= 7.0. To support older operating systems, the icon may be required in the bundle outside of an asset catalog. Make sure the Info.plist file includes appropriate entries referencing the file. See https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleicons

  • 解决方案
    要解决这个问题,就需要在制作时确保所有需要的尺寸都存在
    在苹果官方的设计导航中对所有的icon及尺寸进行了完整说明:human-interface-guidelines/foundations/app-iconsn,但实际所需的跟文档中并不完全一致,不过我们可以从项目的AppIcon中看到。一个常见的同时支持iphone和ipad的app,除去AppStore中需要的一个以外,需要的icon一共18个(iphone和ipad各9个)。一些制作appicon的网站上,也是使用了这样的规则。
    在这里插入图片描述

问题2:文件名重复,导致build失败

  • 遇到的问题
    一开始时我在不同的文件夹下存放了同名的icon文件,例如所有icon都以appicon_尺寸的形式命名,分别存放在自己所在文件夹,最终却导致build失败。
    在这里插入图片描述

  • 解决方案
    出现这个错误的原因是因为xcode在build时,会将所有图片都放在ipa的根目录,如果文件名相同,那么将无法对文件进行管理。下图是展开ipa内容后可以看到的结构。
    在这里插入图片描述

所以在制作icon时,一定要注意保证每个icon的文件名都是唯一的。推荐的命名方式可以参考下一条。

问题3:ios系统找不到图片导致显示没有icon,或是查找的图片尺寸不正确导致icon模糊

  • 遇到的问题
    虽然理论上文件名不会有问题,但我确实遇到了一些奇怪情况,比如当某文件为“appicon_1.png”这样时,系统找不到图片;
    又或者同时包含“appicon-80.png”和“appicon-152.png”这样的文件名时,系统没有使用尺寸最接近的“appicon-152.png”,而是选择了“appicon-80.png”作为appicon导致最终显示模糊。
  • 解决方案
    这些情况都是我们所不想要的,好在只要使用与默认规则一致的命名规则,就可以避免这些情况的发生。
    我在出包后的app中找到了所有被使用的icon,发现命名规则均为AppIcon40x40@2x.png这种类型,其中AppIcon为文件名,40x40@2x为用于标识尺寸的后缀。
    当系统发现所需要查找的名称为AppIcon40x40时,除了AppIcon40x40.png这个文件本身外,还会自动查找所有AppIcon40x40@2x.pngAppIcon40x40@3x.png的文件(如果需要的话)。
    此外,对于ipad,还会在尺寸后缀上再加上一个~ipad用于说明这是ipad上所使用的图片。
    我将所有18个icon的后缀和尺寸整理了一遍,制作icon文件时可以一一对照。
{
	"20x20@2x" : 40,
	"20x20@3x" : 60,
	"29x29" : 29,
	"40x40@2x" : 80,
	"40x40@3x" : 120,
	"29x29@2x" : 58,
	"29x29@3x" : 87,
	"60x60@2x" : 120,
	"60x60@3x" : 180,
	"20x20~ipad" : 20,
	"20x20@2x~ipad" : 40,
	"29x29~ipad" : 29,
	"29x29@2x~ipad" : 58,
	"40x40@2x~ipad" : 80,
	"40x40~ipad" : 40,
	"76x76~ipad" : 76,
	"76x76@2x~ipad" : 152,
	"83.5x83.5@2x~ipad" : 167
}

第二步,配置可更换的icon列表

第二步是进行配置。在info.plist中的配置结构和源代码见下方,其中CFBundleIcons是最外层的入口,在xcode中会显示为Icon files(iOS 5),每一个icon及其配置都是一个字典对象,其中key为在代码中更换时所使用的名称;每个value也是一个字典对象,其中key为CFBundleIconFiles的值包含了一个所引用的图片的列表。图片名查找规则在前文已经进行过说明,不再辍述。
请添加图片描述

对应的配置源文件如下:

<key>CFBundleIcons</key>
<dict>
	<key>CFBundleAlternateIcons</key>
	<dict>
		<key>app_icon1</key>
		<dict>
			<key>CFBundleIconFiles</key>
			<array>
				<string>app_icon160x60</string>
				<string>app_icon129x29</string>
				<string>app_icon140x40</string>
				<string>app_icon120x20</string>
				<string>app_icon176x76</string>
				<string>app_icon183.5x83.5</string>
			</array>
			<key>UIPrerenderedIcon</key>
			<string>false</string>
		</dict>
	...此处省略其他项
</dict>

问题4:在ipad上更换icon无效

  • 遇到的问题
    在完以上面配置后,有可能会遇到仅在iphone上更换成功,但在ipad上更换却无效的问题。

  • 解决方案
    发生这个问题的原因是在ipad上所使用的配置入口与iphone并不相同。在iphone上使用的入口key为CFBundleIcons,但在ipad上需要额外增加~ipad后缀,即CFBundleIcons~ipad
    因此我们需要增加一个ipad专用的入口,内部配置与iphone所使用的完全一致。
    请添加图片描述

具体配置可以参考以下两个链接:

ios文档 Contents of the CFBundleAlternateIcons Dictionary Entry
stack overflow why-do-my-alternate-icons-work-on-iphone-but-not-on-ipad

第三步,编写替换代码

整体代码非常简单,只需要调用api即可。注意setAlternateIconName中所使用的iconName即在上一步中所配置的CFBundleAlternateIcons的key。
例如上方配置了defaulticon_aicon_bicon_d,那么可以使用的iconName就只有这四个。
此外,当iconName的值为nil时,将使用应用默认的icon。

    NSString * iconName = [NSString stringWithUTF8String:icon];
    if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
        return;
    }
    
    if ([iconName isEqualToString:@""]) {
        iconName = nil;
    }

	[[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
		
		if (error) {
			NSLog(@"change appicon %@ with error :%@",iconName,error);
		}
	}];

虽然api很简单,但有时仍会遇到问题。但好在通常都会返回错误信息,根据错误信息调整即可。

问题5:更换icon失败,也没有提示出错

  • 遇到的问题
    在一些场景下无论如何都无法调用成功,也没有错误提示。
    但在xcode中会发现提示要求在主线程中调用。

请添加图片描述

  • 解决方案

在调用更换icon的代码前增加dispatch_async,强制在主线程中调用。


void setAppIcon(const char* icon)
{
	//在主线程中调用
    dispatch_async(dispatch_get_main_queue(), ^{
        _setAppIcon(icon);
    });
}

void _setAppIcon(const char* icon){
    NSString * iconName = [NSString stringWithUTF8String:icon];
    if (![[UIApplication sharedApplication] supportsAlternateIcons]) {
        return;
    }
    
    if ([iconName isEqualToString:@""]) {
        iconName = nil;
    }

    [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {
        
        if (error) {
            NSLog(@"change appicon %@ with error :%@",iconName,error);
        }
    }];

}



参考: ios documentation setAlternateIconName:completionHandler:

以上就是我在配置ios平台可更换代码时遇到的问题,希望可以给到一些帮助。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值