iOS アプリ開発で、とにかく YAML を使いたい! (iOS Advent Calendar 2016)

2016.12.16

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

YAML は読みやすく書きやすい

本ブログは Qiita で開催されている iOS Advent Calendar 2016 の16日目の記事です。前日は koichi_adachi さんで 自作ライブラリをシームレスにObjCからSwiftへ移行する話 でした。

今年は AWS (Amazon Web Services) の CloudFormation というサービスで YAML が対応されたこともあり、とにかく YAML を使う機会が増えました。サーバーサイド界隈では採用されることが多い YAML ですが、iOS をはじめとしたモバイルアプリ開発ではあまり流行っていません。

個人的に感じる YAML のメリットは以下の通りです。

  • 短く簡潔にまとめることができる
  • コメントを書ける
  • 後から読みやすい

このように、JSON に比べた場合のメリットがいくつかあります。そこで iOS アプリ開発で、とにかく YAML を使いたい! と思い立ち、どこで活用できそうか考えてみることにしました。

Info.plist の中身を書き換える

iOS アプリ (Xcode プロジェクト) の設定ファイルといえば Info.plist です。アプリ名 (CFBundleName) やアプリのバージョン (CFBundleVersion / CFBundleShortVersionString) などが定義されているファイルです。アプリの挙動に関わる設定のほか、カスタムの項目を増やしてアプリ上で取得することも可能です。

例えば、位置情報の利用許可をユーザーに確認するときに表示するメッセージを修正してみます。

まずは YAML ファイルを作ります。

info.yaml

location_desc: 好きな文字に変更します。

location_desc は適当に決めたキーです。後述するスクリプトの中で指定することで、値を引っ張ってきます。

次に Info.plist に書き換えるスクリプトを書きます。

add_plist.sh

#!/bin/bash

# Info.plist の場所
INFO_PLIST=Sample/Info.plist

# YAML から Ruby で探す
LOCATION_DESC=$(ruby -ryaml -e "puts YAML.load(ARGF.read)['location_desc']" < info.yaml)

# plutil で書き換える
plutil -replace "NSLocationWhenInUseUsageDescription" -string $LOCATION_DESC $INFO_PLIST

これら2つのファイルを Xcode プロジェクトファイルと同じ階層に配置します。次のような階層になります。

.
├── Sample
├── Sample.xcodeproj
├── add_plist.sh
└── info.yaml

あとはスクリプトファイルを実行するだけです。

$ chmod 755 add_plist.sh && ./add_plist.sh

Info.plist を見てみると、変更されていることが確認できます。

ios-yaml-01

Info.plist の中の書き換えるキーについて今回は決め打ちでしたが、キーを増やすことで、他のカスタム項目を変更することもできます。上記のスクリプトでは毎回 Ruby で YAML を展開するので、より多くの項目を変更したい場合は Ruby で書いた方が良いかも知れません。

JSON ファイルの代わりに使う

設定やちょっとした情報などを JSON ファイルとしてアプリにバンドルしておき、起動時に読むような実装を行うこともあるかと思います。ここで JSON ファイルではなく YAML ファイルを使ってみます。しかしながら、YAML ファイルをパースするライブラリは Objective-C / Swift ともに少ないです。また Foundation フレームワークにある JSONSerialization は、標準でサポートされているという意味でやはり使いたいです。 そこでビルド時に YAML ファイルを JSON ファイルに変換するようにします。こうすることで、書くときは YAML、読むときは JSON を実現することができます。

まずは適当な YAML ファイルを用意します。

app.yaml

message: Hello!

次のようなスクリプトになります。app.yaml という YAML のファイルを用意し、app.json という JSON ファイルに変換しています。

yaml2json.sh

#!/bin/bash

# 前回のファイルを削除
rm -f app.json

# Ruby で YAML を JSON に変換
ruby -ryaml -rjson -e 'puts JSON.pretty_generate YAML.load ARGF.read' < app.yaml > app.json

実行権限を与え得つつ、一度実行しておきます。

$ chmod 755 yaml2json.sh && ./yaml2json.sh

そして、こちらも Xcode プロジェクトファイルと同階層に配置します。

.
├── Sample
├── Sample.xcodeproj
├── add_plist.sh
├── app.json
├── app.yaml
├── info.yaml
└── yaml2json.sh

このうち、先ほど生成した app.json を Xcode プロジェクトから参照できるようにしておきます。

ios-yaml-02

あとは Run Script を追加し、スクリプトを実行するようにします。これで、ビルドするたびに YAML から JSON に変換する処理が実行されるようになります。

ios-yaml-03

まとめ

ということで、iOS アプリ開発の中に、ちょっとだけ YAML を介入させてみました。1つのアプリを作るときにはあまりメリットはないかもしれませんが、環境別に設定を分けたり、1つの Xcode プロジェクトで複数のアプリを作りたいとき、またはテンプレート化したいときなどにきっと役に立つはずです。

明日17日の iOS Advent Calendar 2016 の担当は tarappo さんです。お楽しみに!