Swift Package Managerを使ってアプリアイコンの自動生成ツールを作ってみた

こんにちは。井原 (@nonchalant0303) です。スタディサプリENGLISHのiOSエンジニアをやっています。

今回はiOSアプリのアイコンの管理で使われるAppIcon.appiconsetを自動生成するツールを作成した話について述べていきます。

https://github.com/Nonchalant/AppIcon

🎉 追加 (5/16) GitHubのTrend(Swift)で1位になりました 🎉

ツールを作成する経緯

昨今、Sketch等のUIデザイン作成ツールには、テンプレートなどを使ってiOSアプリのアイコンを各種解像度別にExportする機能があります。弊社では、iOSエンジニアが生成した画像セットを受け取り、Xcode上でAppIcon.appiconsetを作成し、画像をドラッグ&ドロップすることによりアプリアイコンを設定していました。アプリアイコンを設定する作業は頻繁に起きる作業ではないので、マニュアル運用で対応していました。

一部iOSアプリでは季節によってアプリアイコンを変更するなどの施策をしていますが、今まではアプリアイコンを変更するために審査を通してアプリをアップデートしなければなりませんでした。そのため、高速でアプリアイコンを差し替えることによってユーザーの反応を計測するなどの施策が行いづらい環境でした。しかし、iOS10.3から動的にアプリアイコンを変更できるalternateIconNameが使用できるようになりました。事前にアプリにアイコンを組み込む作業が必要ですが、alternateIconNameを使うことにより動的にアプリアイコンを変更することが可能になったので、今後AppIcon.appiconsetを生成する作業が多くなりそうだと感じて自動生成するツールを作ることにしました。

作成物

Demo

https://github.com/Nonchalant/AppIcon


上記のコマンドで各解像度の画像を含んだAppIcon.appiconsetを生成できます。また--outputオプションを使うことにより.appiconsetの生成先のパスも指定できます。

appiconのインストールはHomebrewとソースを落としてインストールする2種類があります。ここでは、Homebrewを使ったインストール方法を紹介します。


Swift Package Managerを使ってみた

Swift Package Manager (SwiftPM)とは、Swift版のライブラリ管理ツールです。Appleが提供しており、CocoapodsやCarthageの代替ツールとして注目されています。また、SwiftPMはコマンドラインツールを作成する機能も備えています。今回はその機能を使うことでコマンドラインツールを作成しました。

開発フロー

Project作成

$ mkdir [Project]
$ swift package init --type executable

上記のコマンドでSwiftPMのProjectを作成することができます。また、Xcode上で開発を進めたい場合は下記のコマンドで.xcodeprojを作成することができます。


$ swift build
$ .build/debug/[Project]

上記のコマンドでmain.swiftの中身が実行することができます。デフォルトではHello, world!と出力されます。

使用したライブラリ

SwiftPMでは外部ライブラリを導入できます。Package.swiftで依存ライブラリを定義できます、CocoaPodsにおけるPodfile、CarthageにおけるCartfileと同じイメージです。AppIconでは下記のライブラリを使用しました。

Commander コマンドライン引数のオプション引数を扱うライブラリ
SwiftShell SwiftでShell Commandを扱うライブラリ
SwiftyJSON SwiftでJSONを扱いやすくするライブラリ

AppIcon.appiconsetの中身は以下のようになっています

AppIcon.appiconset
 ├──Contents.json
 ├──AppIcon-20.0x20.0@2x.png
 ├──AppIcon-20.0x20.0@3x.png
 ├──AppIcon-29.0x29.0@2x.png
 ├──AppIcon-29.0x29.0@3x.png
 ├──AppIcon-40.0x40.0@2x.png
 ├──AppIcon-40.0x40.0@3x.png
 ├──AppIcon-60.0x60.0@2x.png
 └──AppIcon-60.0x60.0@3x.png

SwiftShellで各解像度の画像を生成して、SwiftyJSONでContents.jsonを生成しています。

実装

main.swiftの中に実装していくことも可能ですが、通常のiOS開発と同様にSwiftファイルを追加してコードを分けることも可能になっています。

AppIconの構成は以下のようになっています。

AppIcon
 ├── Document
 │   └── Images
 │       └── appicon.gif
 ├── Gemfile
 ├── Gemfile.lock
 ├── LICENSE.md
 ├── Makefile
 ├── Package.pins (ライブラリのバージョンなどを固定する、自動生成される)
 ├── Package.swift (ライブラリを定義)
 ├── README.md
 ├── Sources
 │   ├── AppIcon
 │   │   └── main.swift (実行ファイル)
 │   └── AppIconCore
 │       ├── AppIcons.swift (アイコンのサイズなど定義)
 │       ├── Command
 │       │   └── Command.swift (Shell Commandのタスクを定義)
 │       ├── Error
 │       │   └── LocalError.swift (Errorを定義)
 │       └── Extractor
 │           ├── Extractor.swift
 │           ├── ImageExtractor.swift (各種解像度の画像を書き出す)
 │           └── JSONExtractor.swift (Contents.jsonを書き出す)
 ├── Tests
 │   └── AppIconTests
 │       └── AppIconsTests.swift
 └── fastlane
     ├── Fastfile
     └── README.md

以下のmain.swiftで各タスクを実行しています。

まとめ

Swift Package Managerでのコマンドラインツール作成は意外と取り掛かりやすいと感じました。使い慣れているライブラリを使用できるのも良いですね!何か要望等ありましたら、IssueやPR, Starなどご気軽によろしくお願いします。

https://github.com/Nonchalant/AppIcon

参考文献