[iOS] アプリアイコンを動的に変更する方法

2017.06.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

アプリアイコンを変える

iOS 10.3 からアプリアイコンをプログラムで変更できるようになりました。
(前までは新しいバージョンをリリースすることでしか変更できませんでした)
今回これを試してみたのでやり方を記します。

動作

1

アイコン変更時に表示されるダイアログは OS が出しているものです。
自分で処理を書いてはいません。
また、アイコンが変更された状態でアプリケーションが終了しても、元のアイコンには戻りませんでした。

1. アプリアイコンをプロジェクトに追加する

変更後のアプリアイコンをプロジェクトに追加します。
ここで重要なのは Assets.xcassets に追加してはいけない ということです。
公式の情報は見つけられませんでしたが、Assets.xcassets に追加した場合はアイコンが変更されないのでご注意ください。

2

2. Info.plist に設定値を追加する

以下の項目を Info.plist に追加します。

<key>CFBundleIcons</key>
<dict>
  <key>CFBundlePrimaryIcon</key>
  <dict>
    <key>CFBundleIconFiles</key>
    <array>
      <string>blue</string>
    </array>
  </dict>
  <key>CFBundleAlternateIcons</key>
  <dict>
    <key>midori</key>
    <dict>
      <key>CFBundleIconFiles</key>
      <array>
        <string>green</string>
      </array>
    </dict>
  </dict>
</dict>

上記の例では blue がプライマリアイコンのファイル名、green が代替アイコンのファイル名、midori がプログラムで使用する代替アイコンのキー値となっています。

  • CFBundleIcons
    • アプリのアイコン情報
  • CFBundlePrimaryIcon
    • アプリのプライマリアイコン情報
  • CFBundleIconFiles
    • アイコンのファイル名
  • CFBundleAlternateIcons
    • アプリの代替アイコン情報
    • 各キー値はプログラムで使用するためのものであり、ファイル名と同一である必要はない
      • 上記の例で midori と書かれている部分

3

3. プログラムを書く

今回私が書いたプログラムは以下の通りです。

import UIKit

class ViewController: UIViewController {

    @IBAction func changeToGreenIcon(_ sender: Any) {
        changeIcon(name: "midori")
    }

    @IBAction func changeToBlueIcon(_ sender: Any) {
        changeIcon(name: nil)
    }

    private func changeIcon(name: String?) {
        UIApplication.shared.setAlternateIconName(name) { error in
            if let e = error {
                print(e)
            }
        }
    }
}

アプリアイコンを変更するためには UIApplication クラスの setAlternateIconName(_:completionHandler:) メソッドを使用します。
代替アイコンに変更したい場合は引数の alternateIconName に Info.plist で指定した CFBundleAlternateIcons のキー値を指定します。
また、プライマリアイコンに戻したい場合は引数に nil を指定します。

以下は UIApplication のヘッダーに書かれている記述です。

// Pass `nil` to use the primary application icon. The completion handler will be invoked asynchronously on an arbitrary background queue; be sure to dispatch back to the main queue before doing any further UI work.
@available(iOS 10.3, *)
open func setAlternateIconName(_ alternateIconName: String?, completionHandler: ((Error?) -> Swift.Void)? = nil)

さいごに

このように、iOS 10.3 からはアプリを再リリースしなくてもアプリアイコンが変更できるようになりました。
どの程度まで Apple が許容するかは分かりませんが、動的にアイコンを変更したい場合は試してみてください。

リンク

ミレニアム・ファルコン製作日記 #76

76 号 表紙

mfd_76_1

パーツ

mfd_76_2

mfd_76_3

mfd_76_4

成果

mfd_76_5

mfd_76_6

今回の作業は以下の 2 つでした。

  • 外殻プレートを取り付ける
  • 穴メカにディテールパーツを取り付ける

今号提供の外殻プレートを、前号で組み立てた外殻フレームに取り付けました。
また、穴メカにもディテールパーツを取り付けましたが、以前ほど複雑な作業ではありませんでした。
今回の穴メカは右舷マンディブル上部に取り付けられる穴メカです。(以前のは下部)

それではまた次回。

May the Force be with you!