【Swift UI】SwiftGenの使い方!画像やカラー、文字列などのリソース管理

この記事からわかること

  • SwiftSwiftGenとは?
  • 導入方法使い方
  • swiftgen.yml作成方法と記述すること
  • 実際に使用する流れ
  • 画像カラー参照方法
  • ローカライズした文字列参照方法
  • AssetL10nとは?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

公式リファレンス:SwiftGen

SwiftGenとは?

SwiftGenは、プロジェクト内で使用するリソース(画像やローカライズされた文字列など)をタイプセーフに参照、管理するためのSwiftコード自動的に生成するCLI(Command Line Interface)ツールです。SwiftGenを使用することでタイプミスの回避や存在しないアセットを参照する可能性を無くしたりとアプリを開発する上で間違いやすいリソースの参照を簡潔に記述することができるようになります。

似たようなライブラリにR.Swiftがありますが、これと同じ役割を持っているのがSwiftGenになります。

導入方法

SwiftGenはCLI(Command Line Interface)ツールなのでプロジェクトごとにというより、Mac自体に導入する形になります。CocoaPodsを使用した方法もあるようですが、Homebrewmintを使用してインストールする流れになります。

Homebrewによるインストール

Homebrewでインストールする場合は以下のコマンドを実行します。

$ brew install swiftgen

Mintによるインストール

Mintでインストールする場合は以下のコマンドを実行します。

$ mint install SwiftGen/SwiftGen

インストールできたか確認してみます。正常にバージョンが返ってくればインストールは成功です。

$ swiftgen --version
SwiftGen v6.6.2 (Stencil v0.15.1, StencilSwiftKit v2.10.1, SwiftGenKit v6.6.2)

swiftgen.yml

SwiftGenでリソースを管理するためには「swiftgen.yml」という名前の構成ファイルを用意する必要があります。これは以下のような役割があります。

このファイルの情報を元にSwiftGenがリソースに対するファイルを自動生成してくれるようになります。「swiftgen.yml」ファイルは以下のコマンドを実行することで自動生成することが可能ですが、手動で作成し設置しても問題ありません。設置場所はプロジェクトのルート階層に設置しておきます。

cd プロジェクト
$ swiftgen config init

生成された「swiftgen.yml」ファイルの中身は全てコメントアウトされているので以下のように書き換えます。


# ローカリゼーション(多言語対応)用Stringファイル
strings:
  inputs: Resources/Base.lproj
  # テンプレート指定と保存先
  outputs:
    - templateName: structured-swift5
      output: プロジェクト名/Generated/Strings.swift
# 画像やカラーコードなどのAssetsリソース
xcassets:
  # 画像やカラーなど
  inputs:
    - プロジェクト名/Resources/Images.xcassets
    - プロジェクト名/Resources/Colors.xcassets
  # テンプレート指定と保存先
  outputs:
    - templateName: swift5
      output: プロジェクト名/Generated/Assets.swift

ここではinputsoutputsでプロジェクト内のファイルを指定しています。inputs側に指定するものはプロジェクト内の実際のパスと合わせるようにしてください。outputs側は自動生成されるのであらかじめ作っておく必要はありません。詳細な設定方法は公式サイトを参考にしてください。

公式リファレンス:SwiftGen 設定ファイル

使い方:画像とカラー

では実際にSwiftGenを使用して画像とカラーをSwiftファイル内から参照してみたいと思います。

流れ

  1. プロジェクトの作成
  2. swiftgen.ymlファイルの準備
  3. プロジェクト内にリソースを用意
  4. 自動生成コマンドの実行
  5. リソースの参照

プロジェクトの作成

まずはXcodeで新規のプロジェクトを作成します。今回は「SwiftGen」というプロジェクトファイル名で作成しておきました。

Xcodeのユーザー登録画面

swiftgen.ymlファイルの準備

続いてswiftgen.ymlファイルを生成し、中に画像とカラーを対象とさせるように記述します。出力先は「Generated/assets.swift」に設定しました。

cd SwiftGen
$ swiftgen config init

# 画像やカラーコードなどのAssetsリソース
xcassets:
  # 画像やカラーなど
  inputs:
    - SwiftGen/Resources/Images.xcassets
    - SwiftGen/Resources/Colors.xcassets
  # テンプレート指定と保存先
  outputs:
    - templateName: swift5
      output: SwiftGen/Generated/Assets.swift

プロジェクト内にリソースを用意

プロジェクト内にリソースを用意していきます。まずはResourcesディレクトリを作成し、その中に「Images.xcassets」と「Colors.xcassets」を作成します。各々に画像やカラーを追加し準備は完了です。この時点での階層構造は以下のとおりです。一応Generatedディレクトリも準備しておきました。

【Swift UI】SwiftGenの使い方!画像やカラー、文字列などのリソース管理

自動生成コマンドの実行

これで準備が整ったのでSwiftGenの自動生成コマンドであるswiftgenまたはswiftgen config runを実行します。

$ swiftgen config run

これでプロジェクト内にGenerated/Assets.swiftファイルが自動生成されました。ですがXcode側からGeneratedディレクトリの中を確認しても見当たりませんでした。プロジェクトをMacのファインダーから見てみるとちゃんと生成されていたのでドラッグ&ドロップでXcode内のGeneratedディレクトリに落とし、「Create groups」にチェックを入れて「Finish」をクリックすることで反映させるようにしました。

【Swift UI】SwiftGenの使い方!画像やカラー、文字列などのリソース管理

これで画像とカラーのリソースに簡単に参照するための準備が完了しました。

リソースの参照:列挙型Asset

画像やカラーのリソースを参照するには列挙型Assetを使用します。この列挙型が自動生成されたデータ型で今回でいう「Assets.swift」に定義されています。例えばロゴ画像(app_logo_name)を指定するString型を参照するにはAsset.Images.appLogoName.swiftUIImage、テーマカラー(thema_color)を指定する場合はAsset.Colors.themaColor.swiftUIColorとなります。

VStack {
    Asset.Images.appLogoName.swiftUIImage
        .imageScale(.large)
    Text("Hello, world!")
        .foregroundColor(Asset.Colors.themaColor.swiftUIColor)
}

Asset.リソースファイル名.リソース名で対象のリソースを参照することができ、そのプロパティからリソースファイル名やリソース型を参照することが可能なっています。

Asset.Images.appLogoName.name // String型
Asset.Images.appLogoName.swiftUIImage // Swift UI Image型
Asset.Colors.themaColor.swiftUIColor // Swift UI Color型

リソースを追加した場合

SwiftGenでリソース管理用のファイルが自動生成された後に画像やカラーなどのリソースを追加した場合は再度ジェネレートする以下のコマンドを実行しないと使用できないので注意してください。

$ swiftgen config run

使い方:ローカライズ文字列

続いてローカライズした文字列をSwiftGenを使用して参照する方法をまとめていきます。「ローカライズって何?」って方は先に以下の記事を参考にしてください。

今回は以下のようにResourcesディレクトリ内にEnglishとJapaneseのLocalizable.stringsファイルがあるとしてやっていきます。この場合Finder上ではResources/en.lproj/Localizable.stringsResources/ja.lproj/Localizable.stringsになっています。

【Swift UI】アプリのLocalization(多言語対応)方法!Localizable.stringsとは?

まずはswiftgen.ymlファイルを以下のように書き換えます。ローカライズされた文字列は端末の言語/地域によって自動で切り替えられて適応されるのでSwiftGenで読み込むのはどれか1つで大丈夫です。今回はja.lproj側にしておきました。


# ローカリゼーション(多言語対応)用Stringファイル
strings:
  inputs:
      - SwiftGen/Resources/ja.lproj/Localizable.strings
  # テンプレート指定と保存先
  outputs:
    - templateName: structured-swift5
      output: SwiftGen/Generated/Strings.swift
# 画像やカラーコードなどのAssetsリソース
xcassets:
  # 画像やカラーなど
  inputs:
    - SwiftGen/Resources/Images.xcassets
    - SwiftGen/Resources/Colors.xcassets
  # テンプレート指定と保存先
  outputs:
    - templateName: swift5
      output: SwiftGen/Generated/assets.swift

ちなみに中には以下のように記述しています。


"language" = "日本語";
"greeting" = "挨拶";
"greeting.morning" = "こんにちは";
"greeting.night" = "こんばんは";

リソースの参照:列挙型L10n

ローカライズされたリソース参照するには列挙型L10nを使用します。そのプロパティとしてLocalizable.stringsファイルのキーとして指定した名前が用意されているので参照できるようになります。

Text(L10n.language)

今回はローカライズする文字列のキーをgreeting.nightのように記述しました。こうすることでSwiftGenで自動生成した列挙型も階層構造にすることが可能です。


internal enum L10n {
  /// 挨拶
  internal static let greeting = L10n.tr("Localizable", "greeting", fallback: "挨拶")
  /// Localizable.strings
  ///   SwiftGen
  /// 
  ///   Created by t&a on 2023/08/03.
  internal static let language = L10n.tr("Localizable", "language", fallback: "日本語")
  internal enum Greeting {
    /// こんにちは
    internal static let morning = L10n.tr("Localizable", "greeting.morning", fallback: "こんにちは")
    /// こんばんは
    internal static let night = L10n.tr("Localizable", "greeting.night", fallback: "こんばんは")
  }
}

階層構造になった場合は以下のように参照できるようになります。

Text(L10n.Greeting.night)

変数を埋め込む方法

SwiftGenではローカライズ時に変数を埋め込む方式にも対応しています。変数を埋め込むには通常のローカライズ通りにキー値側と文字列側%@を入れます。文字列側には表示させたい箇所に%@を埋め込みます。

"capacity" = "容量:%@個";

SwiftGenを実行させると変数を埋め込める箇所は以下のように引数で渡せるようになります。

Text(L10n.capacity(capacity))

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index