【SwiftUI】アプリアイコンを取得してImageとして使用する時の罠と対処法

2022.11.19

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

AppIconに設定している画像を取得してImageとして使用する方法を調べました。

環境

  • Xcode 14.1
  • iOS 16.1
  • Swift 5.7.1

AppIconがSingle Size設定の場合

AppIconを設定する

とてもありがたいことにXcode 14からはAppIconをSingle Size設定にすることで1024x1024の一枚だけを準備すればよくなりました。

今回使用する画像をAppIconに設定します。

画像をAppIconから取得する

AppIconは、UIImage(named:)に文字列"AppIcon"を渡すと取得が可能です。

Image(uiImage: UIImage(named: "AppIcon") ?? UIImage())

しかし、実際に使用してみると、プレビュー上では小さい解像度のものになっています。

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Image(uiImage: UIImage(named: "AppIcon") ?? UIImage())

            Text("Hello, world!")
        }
        .padding()
    }
}

frameを指定してあげて拡大をしてみると、プレビューでは粗い画像になっています。

struct ContentView: View {
    var body: some View {

        VStack {
            Image(uiImage: UIImage(named: "AppIcon") ?? UIImage())
                .resizable()
                .frame(width: 300, height: 300)

            Text("Hello, world!")
        }
        .padding()
    }
}

プレビューではとても粗かったのですが、ビルドしてシミュレータで確認すると綺麗に表示されました。

プレビューだけで確認していると、この罠には気づけないので注意が必要ですね。

AppIconがAll Sizes設定の場合

AppIconを設定する

Xcode 14からはAppIconをSingle Size設定にすることが出来ますが、それ以前のXcodeバージョンでは、All Sizes設定になっています。またXcode 14以上でも、それぞれにサイズに応じたアプリアイコンを提供したい場合にはAll Sizesを選択することがあるかもしれません。

今回は全てのサイズに対して同じデザインの画像を使用する前提で進めていきます。

全てのアプリアイコンのサイズを用意して、設定しました。

UIImage(named: "AppIcon")で画像を取得する

Single Sizeの時と同じようにUIImage(named: "AppIcon")でAppIconを取得してみました。

import SwiftUI

struct ContentView: View {
    var body: some View {

        VStack {
            Image(uiImage: UIImage(named: "AppIcon") ?? UIImage())
                .resizable()
                .frame(width: 300, height: 300)

            Text("Hello, world!")
        }
        .padding()
    }
}

Single Size同様にプレビューでは画像が粗い状態です。

しかし、All Sizesの場合はシミュレータで確認しても粗い状態のままになっていました。

Bundle.main.infoDictionary?["CFBundleIcons"]にアクセスして、高解像度のAppIconを取得する方法も試したのですが、CFBundleIconsには60x60のアイコンしかありませんでした、、。

CFBundleIcons:  [
    "CFBundlePrimaryIcon": {
        CFBundleIconFiles =     (
            AppIcon60x60
        );
        CFBundleIconName = AppIcon;
    }
]

おまけ

All SizesからSingle Sizeに切り替えると用意していた1024x1024以外の画像が削除されます。遊び半分で切り替えるのはやめた方が良さそうです。

allsize-to-singlesize

まとめ

  • Single SizeのAppIconを使用する場合は、プレビューでは解像度が粗いままで表示され、シミュレータだと解像度の高い状態で表示される
  • All SizesのAppIconを使用する場合は、プレビューでもシミュレータでも解像度の粗いままで表示される

以上を踏まえると、AppIconを使用する時は、AppIconとは別に画像アセットを用意して使用する方がプレビューでも正常に表示され、より安全安心と感じました。

参考