SwiftGenを使ってみた
はじめに
アプリの画面作成においてStoryboard
をメインに使用しており、Color
やImage
をアセットフォルダで管理しています。
Storyboard名
やColor
、Image
のタイポの可能性をなくしたいと考え、コード生成ライブラリの一つであるSwiftGenを使用してみました。
SwiftGenとは
説明不要かもしれませんが、SwiftGen
は、プロジェクトのリソース(画像やローカライズされた文字列など)に対してSwiftコードを自動的に生成し、タイプセーフな状態で使用できるようにするツールです。
SwiftGenを使用することには、いくつもの利点があります。
There are multiple benefits in using this:
- Avoid any risk of typo when using a String
- Free auto-completion
- Avoid the risk of using a non-existing asset name
- All this will be ensured by the compiler and thus avoid the risk of crashing at runtime.
(https://github.com/SwiftGen/SwiftGen より引用)
タイポのリスク回避や、存在しないアセットの使用リスクの回避などが挙げられています。
また、Swift製のStencil
というテンプレート言語を使用することで、適切なSwiftのバージョンでコードを生成できます。
ただし、解析対象は限られており、
- Asset Catalog
- Colors
- Core Data
- Fonts
- Interface Builder (Storyboard)
- JSON と YAML
- Plists
- Strings (ローカライズ)
が挙げられています。
既に多くの記事で言及されていると思いますが、Xibは適用外なので、別の方法でタイポを防ぐようにする必要があります。
導入手順
SwiftGenのインストール
Cocoa Pods
でインストールしました。
pod 'SwiftGen'
Cocoa Pods
を使用しましたが、SwiftGen
はアプリ側での設定はほぼなく、swiftgen.yml
ファイルという設定ファイルに「どのファイルを解析するか」、「どのテンプレートを使用するか」、「生成されたファイルをどこに置くか」を指定するだけで使用できます。
設定ファイル (swiftgen.yml)の作成
まず、設定ファイルswiftgen.yml
を生成するために、プロジェクトのルートディレクトリで以下のコマンドを実行します。
(初めての場合は、Homebrew
などでSwiftGen
をインストールしてから以下を実行してください。)
$ swiftgen config init
これで、カレントディレクトリにswiftgen.yml
ファイルが作成され、中身は各種設定例がコメントアウトされたものとなっています。
swiftgen.ymlの構成
次に、Swiftgen.yml
を編集します。
例えば、今回はColor、Image、Storyboardのコード生成したいので、以下のように書けます (あくまで一例です)。
input_dir: [プロジェクト名]
output_dir: [プロジェクト名]/Generated/
xcassets:
inputs:
- Resources/Colors.xcassets
- Resources/Images.xcassets
outputs:
- templateName: swift5
params:
forceProvidesNamespaces: true
output: Assets.swift
ib:
inputs: .
outputs:
templateName: scenes-swift5
output: Storyboards.swift
中身の簡単な説明です。
-
input_dir
はフォルダパスです。Storyboardやアセットフォルダなどの生成元の共通のフォルダパスを指定しています。 -
output_dir
は生成したコードをどこに置くかパスを指定しています。生成したコードを置くためのGenerated
ディレクトリを作成しました。 -
xcassets
はアセットフォルダ、ib
はStoryboardが解析対象であることを指定しています。 -
inputs
は解析対象のファイルパスを示します。inputs_dir
を設定してる場合、inputs
はinputs_dir
からの相対パスであることに注意が必要です。
Colors.xcassets
とImages.xcassets
を置くResources
フォルダを作成しています。また、「. (ドット)」
を指定することで、プロジェクトディレクトリの中身のStoryboard全てを対象にしています。
Storyboardは画面ごとに作成しているため、ディレクトリが分かれており、このように書けるのはありがたいですね。 -
templateName
には先述したテンプレートを指定します。
使用できるテンプレートのリストを確認したいときは、以下のコマンドを実行して確認できます。
$ swiftgen template list
-
output
は生成コードのファイル名です
設定ファイルのlint
swiftgen.yml
ファイルの中身が正しく書かれているか、以下のコマンドでチェックできます。
$ swiftgen config lint
少しハマったのが、余計なスペースなどがあるとエラーになるので、なぜか上手くいかないときはインデントを揃えてみると良いと思います。
SwiftGenを実行する
設定ができたらPods/SwiftGen/bin/swiftgen
を実行すれば、指定したパスにコードが生成されます。
ここまで、ビルドなしでコードが生成でき、使用できるのも特徴の一つです。
ただし、swiftgen.yml
を変更するたびに実行するのが面倒な場合は、Xcode
のRunScript
に以下のように記述しておけば、ビルドのたびに差分を見て変更があればコードを生成してくれます。
${PODS_ROOT}/SwiftGen/bin/swiftgen config run --config $SRCROOT/swiftgen.yml
今回の記事の例だと、実行結果は以下のようなファイル構成になります。
使用例
今回、StoryboardとAsset Catalogを対象にコード生成しました。それらの使用例は以下のようになります。
Asset Catalog
//before
imageView.image = UIImage(name: "cat")
//after
imageView.image = Asset.Images.cat
Storyboard
//before
let hogeVC = UIStoryboard(name: "Hoge", bundle: nil).instantiateInitialViewController() as! HogeViewController
//after
let hogeVC = StoryboardScene.Hoge.initialScene.instantiate()
最後に
SwiftGenを使用してみた感じ (主観)としては、
メリット
-
ビルド
でもコマンド
からでもコード生成できる - 解析対象や生成ファイルの
パス
を柔軟に設定できる - 解析対象の名前を大文字始まりにしていても、
キャメルケース
でコード生成してくれる - 何より
タイポ
の可能性を減らすことができる -
swiftgen.yml
ファイルさえあれば、同じルールでコード生成できる
一応デメリット
(他のコード生成ライブラリを使用したことがないため、比較はしていません)
- Xibファイルからコード生成できない (自分は必要としているため)
- 一番最初にコード生成したときは、生成したファイルをXcodeにわざわざ追加しないと参照されない
(これについては、原因が分かっておらず、もし読んでいただいた方でわかる方がいれば、コメントいただけると幸いです。)
今後も使用していくと思うので、追加で分かったことや修正があれば追記していきます。
参考文献
この記事は、以下の情報を参考にしました。
Author And Source
この問題について(SwiftGenを使ってみた), 我々は、より多くの情報をここで見つけました https://qiita.com/mtkmr/items/15a1273c205823540971著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .