プロダクトにSwiftGenを導入してタイポ0の世界を作る

こんにちは。
自動貯金サービス『しらたま』でiOSエンジニアをしています、Objective-ひろC(@hirothings)です。

今回はマネーフォワードのiOSアプリで活用しているSwiftGenというコードジェネレータについてご紹介します。

 

SwiftGenとは?

下記のように、タイプセーフにリソースが扱えるコードジェネレータツールです。
文字列直打ちの指定と違って、typoでランタイムエラーになることを防ぐことができます。
https://github.com/SwiftGen/SwiftGen

// Before
imageView.image = UIImage(name: "icon20Star")

// After
imageView.image = Asset.Common.icon20Star.image

リソースの削除や名前の変更があった場合は、コンパイル時にエラーになるので便利です。

SwiftGenは、

  • Assets Catalogs
  • Colors
  • Fonts
  • Interface Builder files
  • Localizable.strings

のリソースに対応しています。

先発で有名なR.Swiftより設定の幅が広い分、少し導入の難易度が高いです。

ただ、プロダクトに導入してみると本当に痒いところに手が届くライブラリです。

 

基本的な使い方

SwiftGenは基本的には、 swiftgen storyboards -t swift4 ./path/to/storyboards のようにCLIで利用するライブラリです。
ただ、毎回コード生成のたびに上のようなコマンドを打つのは辛いので、いくつかチームで利用するための整備をして利用しています。

 

プロダクトでの利用環境

インストール

homebrew経由でも利用できますが、複数人で利用することを考えてcocoapods経由でインストールしています。

設定ファイルを活用

設定ファイル (swiftgen.yml) をプロジェクトのルートに置いておくと、この設定ファイルを自動で読み込むので、毎回のコマンドは swiftgen だけで済みます。

設定ファイルの (一部)

SwiftGenは、 Stencil というSwift製のテンプレート言語を採用していて、これによって指定した templateName のSwiftのバージョンでコードを生成できます。

採用したprojectはAsset Catalogが複数ある構成だったのですが、下記のように複数指定することもできます。

output_dir: ./{プロジェクト名}/Generated
storyboards:
  templateName: swift4
  paths: {プロジェクト名}
  output: StoryBoards.swift
  params:
    ignoreTargetModule: true
    module: XXX
xcassets:
  templateName: swift4
  paths:
    - {プロジェクト名}/Resources/Common.xcassets
    - {プロジェクト名}/Resources/XXXImage.xcassets
    - {プロジェクト名}/Resources/YYYImage.xcassets
  output: AssetsImages.swift

詳しくは https://github.com/SwiftGen/SwiftGen/blob/master/Documentation/ConfigFile.md を参照してください。

実行

swiftgen の実行は、runscript経由で自動化しています。

${PODS_ROOT}/SwiftGen/bin/swiftgen

それと併用して、ファイルを追加した時などは適宜 swiftgen コマンドを叩いて、ビルドなしで生成したコードを利用できるようにしています。

使用例

こんな感じで使用しています

Asset Catalog

// Before
imageView.image = UIImage(name: "icon20Star")

// After
imageView.image = Asset.Common.icon20Star.image

StoryBoard

// Before
let viewController = UIStoryboard(name: "Hoge", bundle: nil).instantiateInitialViewController() as! HogeViewController

// After
let viewController = StoryboardScene.HogeViewController.initialScene.instantiate()

LocalizableStrings

self.title = NSLocalizedString('hogeViewTitle', comment: "")

// After
self.title = L10n.hogeViewTitle

Xibについて

SwiftGenは、Xib用のコード生成に対応していないため、Mixinとしてオススメされている Reusable というライブラリを併用しています。
Reusableは最近活動が活発ではないですが、Swift4でmigrationするコードがなくシンプルな実装なので、改修の余地がないようです( https://github.com/AliSoftware/Reusable/issues/50 )。

Swift4のプロジェクトで利用していますが、問題なく利用できています。

まとめ

他のコードジェネレータと違って、
1. 差分ビルドなためコード生成が一瞬で終わる
2. コマンドから生成できる = コード生成のためのビルドをする必要がない
3. 生成コードのpath, 生成元コードのpathなど設定が柔軟

な点がSwiftGenの良い点かと思います。
特にコード生成のためのビルドをしなくとも、コマンドでパッと生成したコードを使えるのはすごい快適ですので、利用されたことのない方は導入を検討してみてください。

最後に

マネーフォワードでは、一緒に働いてくれるiOSエンジニアを募集しています。
ご応募お待ちしています。

【採用サイト】
マネーフォワード採用サイト
Wantedly | マネーフォワード

【マネーフォワードのプロダクト】
自動家計簿・資産管理サービス『マネーフォワード』
Web
iPhone,iPad
Android

「しら」ずにお金が「たま」る 人生を楽しむ貯金アプリ『しらたま』
Web
iPhone,iPad

ビジネス向けクラウドサービス『MFクラウドシリーズ』
バックオフィス業務を効率化『MFクラウド』
会計ソフト『MFクラウド会計』
確定申告ソフト『MFクラウド確定申告』
請求書管理ソフト『MFクラウド請求書』
給与計算ソフト『MFクラウド給与』
経費精算ソフト『MFクラウド経費』
入金消込ソフト『MFクラウド消込』
マイナンバー管理ソフト『MFクラウドマイナンバー』
資金調達サービス『MFクラウドファイナンス』

メディア
くらしの経済メディア『MONEY PLUS』

Pocket