改变iOS app的icon(iOS10.3)

改变iOS app的icon

官方

iOS10.3新增了可以让开发者去更改app的icon,接下来看看怎么更改。
官方API给的东西很少,只是介绍了一个实例方法:

open func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Swift.Void)? = nil)

根据传入的参数可知,我们只需要传入备用icon名字即可,然后在回调里面拿到修改的结果,成功的话error为空,不成功则返回相应的错误信息(可以使用error!.localizedDescription来打印查看错误信息)。如果失败的话,alternateIconName属性不变。这里注意:

如果当期app使用的icon是备用的icon,那么这个属性的值就是当前icon的名字,这个名字是在Info.plist里面设置的名字,如果当前app展示的是主要(primary)的icon,那么这个值为nil。

这里需要注意两点:
1. 当前设备的系统版本。这里的所有api都是10.3才能使用的。
2. 当前app是否支持备用icon。使用supportsAlertnateIcons属性判断。只有为true的使用才能去更改。
API中还有一句话比较关键:

你必须在Info.plist里面使用CFBundleIcons声明当前app的primary和alternate icon。这里如果不了解可以往下看,先忽略。

具体的Info.plist里面的字段含义这里就不在一一说明,详情可了解这里

总之官方API上面我只找到了这么多。然而给我的感觉反倒一脸懵逼,完全搞不懂下面的Info.plist怎么设置。因此有了下面的序文。

个人理解

在刚才的Info.plist key介绍里面,我们先看一下其他的小知识。
我们都知道在Info.plist里面有个Bundle display name,也就是设置app在桌面显示的名字。此时如果我们先不管这个key,我们继续在Info.plist里面添加CFBundleDisplayName,你会收到这样一个提示:

The key you entered is already present in the dictionary.do you want to replace the existing key/value pair?

但是看一下Info.plist字典中的key,并没有CFBundleDisplayName,替换后发现,原来它就是Bundle display name。也就是说,Info.plist里面的Key在Xcode中显示的并不是Key,而是Xcode name。如下图:

这个是从官方API上截的图,其实这些Key都有对应的Xcode name,也就是在Xcodes里面我们能看到的key。其实也很简单,如果你把Info.plist使用源码形式打开(右击—>Open as —>Source code),你就会发现这里写的key就是上面列出来的key。

先看看我在网上查资料设置的Info.plist:

这里的CFBundleIconFiles是备用icon的名字。下面的Primary Icon是默认的icon。源代码就是:

其中CFBundleIcons对应的就是Icon files(iOS 5),CFBundleIconFiles就是Primary Icon。
先看一下CFBundleAlternateIcons。这个CFBundleAlternateIcons key所对应的value在iOS里面是一个字典,例如:

每个字典的key是备用icon的名字,这个也是你传入到

IApplication.shared.setAlternateIconName(iconName) { (error) in
            if (error != nil) {
                self.aler(str: (error!.localizedDescription))
            }else {
                self.aler(str: "修改成功")
            }
        }

里面的iconName。其中的字典对应值解释如下:

CFBundleIconFiles:这个是一个String的数组,里面每个元素都是icon 的名字,你可以添加多个不同大小的icon来支持iPhone,iPad。
UIPrerenderedIcon:指定应用程序的图标是否包含闪光效果(shine effect),如果icon已经有这个效果,就把这个属性设置为YES来防止系统再次添加相同效果。如果设置为NO(默认值),iOS系统会自动添加这个效果。然而,我并没有测试出来这个效果!!
这里还要注意一下:Primary Icon的Item 0的name也可以不填写,苹果官方文档也没有具体说名字这个要怎么去填写,只是说如果你想使用CFBundlePrimaryIcon键值定义的icon,直接使用将setAlternateIconName的参数alternateIconName写成nil就行。在属性列表里面直接不填写就行(即把AppIcon60x60删掉)

自己新建一个项目实现

自己实现需要注意两个问题:
1. Info.plist怎么设置?
2. 备用图标icon放到哪里?

首先来设置Info.plist。
按照苹果官方的API说法,那就先在Info.plist里面添加CFBundleIcons。但是查看了一下Key和Xcode name对应的表格,CFBundleIcons对应的是None,那就直接添加CFBundleIcons吧。点击Information Property List后面的加号,输入CFBundleIcons,当点击Enter键的时候,你会惊奇发现:你添加的CFBundleIcons变成了Icon files(iOS 5)字典。看看CFBundleIcons的官方API:

根据英文意思可以知道:该key包含了所有app使用的icons信息。新建的是这样的:

可知默认的包含了CFBundlePrimaryIcon和UINewsstandIcon。里面没有CFBundleAlternateIcons,(我理解的应该是苹果不太想支持用户添加备选icon,所以才没有)。这里不过多介绍UINewsstandIcon了,它应该是在NewStand上展示的吧,不太清楚,想了解可以看API,里面介绍了。
现在把NewStand Icon删除,添加CFBundleAlternateIcons。添加后如图所示:

但是看官方API对CFBundleAlternateIcon的介绍里面,并没有UINewstandBindingType和UINewsstandBindingEdge,只有这个:

也就是官网所说的只有CFBundleIconFiles和UIPrerenderedIcon,那就删了多余的那两个UINewstandBindingType和UINewsstandBindingEdge。然后添加UIPrerenderedIcon:
。按照苹果的说法,把备用图标的名字放到Items0里面。我们先直接在左侧导航中加入两张图片:newicon@2x.png 和newicon@3x.png,一个120 120,一个180 180。
但是看到上图说的设置,跑起来运行代码:

    @IBAction func changeToNewIconAction(_ sender: Any) {
        if !checkSupportChangeIcon() {
            return
        }
        if !UIApplication.shared.supportsAlternateIcons {
            return
        }
        changeToIcon("newicon")

    }
    //MARK: check system version
    func checkSupportChangeIcon() -> Bool {
        let deviceVersion = UIDevice.current.systemVersion
        if deviceVersion.contains("10.3") {
            return true
        }
        return false
    }
    //MARK: change to icon message
    func changeToIcon(_ iconName: String?)  {

        UIApplication.shared.setAlternateIconName(iconName) { (error) in
            if (error != nil) {
                self.aler(str: (error!.localizedDescription))
            }else {
                self.aler(str: "修改成功")
            }
        }

    }
    //MARK: alert message
    func aler(str: String) {
        let alert = UIAlertController.init(title: "提示", message: str, preferredStyle: .alert)
        let okAction = UIAlertAction.init(title: "ok", style: .cancel) { (action: UIAlertAction) in
            print("关闭弹出框")
        }
        alert.addAction(okAction)
        self.present(alert, animated: true, completion: nil)
    }

结果却是:

The file doesn't exist

看了一下官方API对CFBundleAlternateIcons的介绍,里面有一句话:

In iOS, the value of the key is a dictionary. The key for each dictionary entry is the name of the alternate icon, which is also the string you pass to the setAlternateIconName:completionHandler: method of UIApplication when changing icons. The value for each key is a dictionary containing the keys in Table 5

意思是这个CFBundleAlternateIcons中的字典的key是备用icon的名字,因此需要这样修改:

也就是CFBundleAlternateIcons字典里面的key是备用icon的名字,然后以名字为key的字典里面又包含了CFBundleIconFiles和UIPrerenderedIcon。
这样设置之后再次运行你会发现成功更改了icon。
这样就成功地改变了icon。
关于Primary Icon,直接不用设置Icon files就好了,如果你想设置为默认的icon,就在setAlternateIconName里面传入nil就好了。这个时候Info.plist源码长这样:

在Property List里面,Primary Icon的Icon already includes gloss effects就是UIPrerenderedIcon,它的设置为false。(这里的光泽效果也是没有测试出来有什么不一样)
接下来看看备用icon是在哪里放着呢?
开始的时候直接放到这里:

发现是OK的,可以正常显示。
那么放到Assets.xcassets里面呢?放到Bundle里面呢?接下来将每个case都进行测试:

  • 放到Assets.xcassets里面。新建一个普通的Image set,然后将图片放到里面,效果如图所示:

    经过测试发现,这样放置是无法正常改变appicon的。但是运行结果没有任何错误,而且系统提示里面加载的也是新的app icon:
  • 放到Assets.xcassets里面,并且新建的icon,如图:

    运行依然设置不成功。没有错误提示
  • 放到一个新建的Bundle里面。如图所示:。

    运行结果依然是没有成功更改。没有错误提示。

所以经过测试,发现只有放到导航里面的图片才可以更改成功。在苹果qa里面看到过一个场景,他们是直接在导航新建了一个文件夹,然后将图片放到里面,然后使用。这里也推荐建立文件夹放入图片,然后使用

另外,关于icon大小,可以参见这里

最后告诉大家一个不使用Asset来配置Icon的方法:直接在Info.plist下面这样写:

这个是通用的,可以直接设置iPhone和iPad的icon。其实这里也是想告诉大家:如何在CFBundleIconFiles里面去添加图片数组:

 <key>CFBundleIconFiles</key>
            <array>
                <string>Icon-Small</string>
                <string>Icon-Small-40</string>
                <string>Icon-Small-50</string>
                <string>Icon</string>
                <string>Icon-60</string>
                <string>Icon-72</string>
            </array>
备注
  1. 如果有什么疑问欢迎留言提问。或直接加群:206613455
  2. 源码地址:https://github.com/ScottZg/iOSChangeAppIcon
时间: 2024-12-02 19:59:40

改变iOS app的icon(iOS10.3)的相关文章

iOS App设置icon,启动图,App名称的方法

每款App都要有自己的icon,和名称.需要的话还需要设置启动图. 今天我们就来说一下如何设置这些.本篇博客暂不讨论关于尺寸的问题. icon: icon的设置还是很简单的 根据上图的箭头和红框标记所示, 首先在工程中选中"images",然后选择"AppIcon",把预先准备好的各个尺寸的icon拖到相应的框中. App名称: 如图所示 选择你的工程,选中"Info",再点击"Bundle Display Name",在后面

如何用 React Native 创建一个iOS APP?(二)

我们书接上文<如何用 React Native 创建一个iOS APP?>,继续来讲如何用 React Native 创建一个iOS APP.接下来,我们会涉及到很多控件. 1 AppRegistry.registerComponent( 上述是定义应用程序的入口点.这也是 JavaScript 代码开始执行的地方.  这是一个本地用户界面反应的基本结构.我们定义的每个视图将遵循相同的基本结构. 在本教程中,我们将创建一个既可以浏览书籍又能知道书籍介绍比如作者.标题或关于书籍的简介.你还可以通

ios app应用程序发布到app store流程

1,首先你需要有一个apple developer开发者账号,登入后台. 需要创建一个发布者证书,可以看到上面我 已经创建了一个开发者证书,下面是新创建的发布证书. 创建的步骤如下: 打开mac的钥匙串管理, 生成一个CertificateSigningRequest.certSigningRequest 文件,然后在新建一个证书,如下图: 然后将生成的CertificateSigningRequest.certSigningRequest文件选择上传,生成一个证书文件,下载双击安装. 再此查看

《iOS App界面设计创意与实践》——快速提示:iOS开发策略

快速提示:iOS开发策略 iOS App界面设计创意与实践 在我们深入iOS UI.动画和手势背后的技术之前,掌握一些基础知识很重要.对于设计师而言,虽然不要求读完本书后能够编写代码,但是有一些标准的iOS开发策略,开发者或者必须在基于iOS SDK开发中遵循,或者应该作为最佳实践来遵循.作为设计师,了解这些因素对开发人员的影响,对于理解如何设计最佳用户体验是至关重要的.作为开发人员,快速温习一下最佳实践并没有害处. 模型-视图-控制器 当谈及编码原则时,模型-视图-控制器(MVC)是最基础的.

html5 &amp;amp;amp; android,ios app

问题描述 html5 & android,ios app 准备开始学html5,但是有几个问题不是很清楚,望各位大神帮忙解惑... html5移动web设计,是为了用户使用各种手机能良好的访问网站. 貌似在哪听说的html5移动app取代android,ios这类的app,不是很明白, 假如说真到了那个时候,html5发展很NX的说,用户可以在手机上像使用电脑一样方面的访问任何页面内容,包括页游,那么是不是说,app基本没什么用了?用户手机只需要安装一个浏览器,然后就能各种玩起了? 还是说and

iOS APP 中的不可变模型以及一致性数据

本文讲的是iOS APP 中的不可变模型以及一致性数据, 今年早些时候,为了给用户,尤其是大部分海外的用户更快更清晰的体验,我们全面重构了我们的 iOS 应用.这次重构的其中一个目的是将我们的应用迁移到一个不可变模型的层面上.在这篇博客中,我将会讨论这样做的动机,并探索我们的新系统是如何处理模型的更新,从 API 读取新信息,以及保持数据持久性的. 为什么选择不可变模型? 因为现今许多应用都转而使用了不可变设计,'不可变模型'已经成为了一个耳熟能详的术语.不可变性意味着再初始化后模型将不可再更改

IOS开发之适配iOS10及Xcode8的注意点_IOS

下面给大家介绍下iOS10的适配及Xcode8使用上的一些注意点,一起看看! 一.证书管理 用Xcode8打开工程后,比较明显的就是下图了,这个是苹果的新特性,可以帮助我们自动管理证书.建议大家勾选这个Automatically manage signing(Ps.但是在beat2版本我用的时候,完全不可以,GM版本竟然神奇的又好了.) 下面我来说说可能会出现的问题: 1.Xcode未设置开发者账号情况下的截图 解决办法是:大家在Xcode的偏好设置中,添加苹果账号,即可. 2.设备机器未添加进

iOS开发之适配iOS10以及Xcode8_IOS

iOS开发:适配iOS10以及Xcode8 现在在苹果的官网上,我们已经可以下载到Xcode8的GM版本了,加上9.14日凌晨,苹果就要正式推出iOS10系统的推送了,在此之际,iOS10的适配已经迫在眉睫啦,不知道Xcode8 beat版本,童鞋们有木有下载过来试试呢?就我的使用来说,总体觉得苹果还是坑不断,但是也在一直进步的啦.下面我就来说说,iOS10的适配以及Xcode8使用上的一些注意点. 一.证书管理 用Xcode8打开工程后,比较明显的就是下图了,这个是苹果的新特性,可以帮助我们自

objection - 基于 Frida 的 iOS APP Runtime 探测工具

本文讲的是objection - 基于 Frida 的 iOS APP Runtime 探测工具, 介绍 在这篇文章中,我想介绍一下我一直在研究的一个工具包,叫做objection.这个名字其实所隐含的意思就是"object"以及"injection".objection是由Frida提供的可以对移动平台的runtime进行检测的工具包.该工具包目前只在iOS上,其旨在允许您能够在非越狱iOS设备runtime时,在其未加密的iOS应用程序上执行各种安全相关的任务.