はじめに
アプリのアイコンを季節やイベントごとに変更しているアプリを最近よく見かけますね。
今までは、アプリを申請して変更しなければいけなかったのですが、
iOS10.3からは申請なしで、アプリのアイコンを変更できるようになったようです。
TwitterのアイコンをFacebookのアイコンに変更してみました。
Alternate Icons
UIApplicationのExtensionに追加されたようです。
extension UIApplication {
    // If false, alternate icons are not supported for the current process.
    @available(iOS 10.3, *)
    open var supportsAlternateIcons: Bool { get }
    
    // 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)
    
    // If `nil`, the primary application icon is being used.
    @available(iOS 10.3, *)
    open var alternateIconName: String? { get }
}
setAlternateIconName(_:completionHandler:) - UIApplication | Apple Developer Documentation
また、アイコンの変更はフォアグラウンドの状態に限定され、
変更後はユーザにダイアログで通知されるようです。
実装
- アイコンを登録する
- Info.plistに必要項目を登録する
- アイコンを変更する処理を実装する
1.アイコンを登録する
アイコンは、アセットカタログを利用するとうまく行きませんでした。
そのため、プロジェクト配下に保存しました。
 
2. Info.plistに必要項目を登録する
(1) Add Rowで行を追加し、「アイコンファイル(iOS 5)」を選択します。
(2) Primary Icon > Icon files > Item0にデフォルトのアイコン名を入力します。
(3) 入れ替えるアイコン用にCFBundleAlternateIconsを追加します。
(4) CFBundleAlternateIcons > 任意の名前を入力します。
(5) CFBundleAlternateIcons > 任意の名前 > CFBundleIconFiles > Item0に入れ替えるファイル名を追加します。
今回は、facebook Icon、Instagram Iconとしました。
この値は、ソースコードで利用します。
 
3. アイコンを変更する処理を実装する
ボタンを押下して、アイコンを変更します。
import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func didTapChangeIcon(_ sender: UIButton) {
        // Info.plist で設定した値
        let iconName = "facebook Icon"
        UIApplication.shared.setAlternateIconName(iconName) { error in
            if let error = error {
                print(error.localizedDescription)
            }
            print("Done!")
        }
    }
}
まとめ
時計やカレンダーアプリのような動的な変更はできないようですが、
季節やイベントごとにアイコンを変えたい時に、活用できそうですね。
参考
Swift World: Change your app’s icon programmatically in iOS 10.3

