iOS Advent Calendar 2019 3日目のかっくん(@fromkk)です。
XcodeでiOSアプリなどを開発してて独自のwarningをXcode上に表示したいなと思う事がありました。
調べてみるとRun Script
に標準出力で決まった記法で表示すると独自のワーニングやエラーを表示する事が出来る事が分かったのでまとめておきます。
ファイルなどの指定無し
# warning
echo "warning: some warning message"
# error
echo "error: some error message"
これをRun Scriptに記入するだけでワーニングとエラーが表示されます。
ファイル指定
# warning
echo "/path/to/your/file: warning: some warning message"
# error
echo "/path/to/your/file: error: some error message"
これだけでファイルを指定してワーニングとエラーが表示されます。
行数と文字の箇所指定
line=61
column=28
# warning
echo "/path/to/your/file:$line:$column: warning: some warning message"
# error
echo "/path/to/your/file:$line:$column: error: some error message"
と指定すれば該当の行数と文字の箇所にワーニングとエラーが表示されます。
尚、Run Script
でエラーを表示するだけではビルドは止まりません。
(exit 0
以外のステータスを返せば止まるはず)
typoを見つける為のツールを作ってみた
上記のフォーマットを利用してtypoを見つけるためにSpellCheckerというCLIツールを作ってみました。
インストール方法は
git clone git@github.com:fromkk/SpellChecker.git
cd ./SpellChecker
make install
でインストール可能です。
使い方
CLIツールとしても利用可能なので、
/usr/local/bin/SpellChecker -yml WhiteList.yml -- /path/to/ViewController.swift /path/to/Model.swift
の様な感じで利用可能です。
-yml
の後にワーニングを無視するためのYAMLファイルのパスを指定することができます。
また、 --
の後ろにスペルチェックしたいファイルのパスの一覧を渡します。
YAML
対応しているフォーマットは
whiteList:
- kazuya
- ueoka
- fromkk
の様な感じです。
Run Script
Xcodeのプロジェクトに新しくRun Scriptを追加して下記の様なコードを追加します。
if ! [ -f /usr/local/bin/SpellChecker ]; then
echo "SpellChecker not installed"
exit 0
fi
git_path=/usr/local/bin/git
files=$($git_path diff --diff-filter=d --name-only -- "*.swift" "*.h" "*.m")
if (test -z $files) || (test ${#files[@]} -eq 0); then
echo "no files changed."
exit 0
fi
options=""
for file in $files
do
options="$options $SRCROOT/$file"
done
/usr/local/bin/SpellChecker -yml $SRCROOT/whitelist.yml -- $options
これでコードを適当に変更してビルドすると
こんな感じでwarningが表示されるのでどこでタイポしているかが一目瞭然になります。
良かったらスター ください
SpellChecker
開発にあたって考えた事など
typoを検知する仕組みについて
いくつか検討・実装をしてみて一番簡単でコストの掛からない方法を模索していました。
ざっと以下の様な感じです。
- ツールからcspellをそのまま呼ぶ事を検討したが 却下
-
cspell
が重たいのが気になった - 出力結果の変換が面倒
- 外部ツールへの依存はあまりしたく無かった
- cspellを参考にして単語リストを作成して、リストに無い場合はタイポと見なす方法を検討したが 却下
- 単語リストが重たい
- 重たいリストを読み込んでパースする処理も比例して重たい
- Swift Package Managerではリソースを持つ事が出来なかった
- Xcode上で使われる事を想定するとLinuxの事を考える必要が無いなと思い、macOSが持ってる辞書を利用出来ないかを検討したが 却下
- 精度が悪い(想像以上に辞書に登録されている単語が少なかった)
- Private APIを利用しないと辞書の選択が出来ない(しかもObjective-Cからしか利用出来ない)
- スペルチェックで調べているとUITextCheckerというものを発見し、iOSにあるならmacOSにもあるだろと調べていたらNSSpellCheckerを発見し良さそうだったので 採用
- 逆に精度が高すぎて
hoge
やfuga
などがタイポにならないのが少し気になる - 運用する中で検討していきたい
補足(謝辞)
ちなみに、念の為、他にも同様のツールが無いか簡単に調べた上で作ったんですが、上記の NSSpellChecker
の使い方を調べている中で @ezura さんの ezura/spell-checker-for-swift を発見しました。
完全に用途も被っており途中で作るのを諦めるか悩んだのですが、ezuraさんの方がSwiftSyntaxを利用している事を発見し、Swiftファイルに限定された用途なのだと理解しました。
僕の方はあえてSwiftSyntaxを利用せず、半角英字を見つけたらスペルチェックをする様にしているので特にファイル形式を問わない様に作っています。
どちらが良い・悪いというものでもなく、用途に合わせて良いなと思った方を使って頂ければと思います
尚、 NSSpellChecker
の使い方はとても参考にさせて頂きました。ありがとうございました
まとめ
Advent Calendarドリブンで色々調べたり開発をしたりしてたのですが、結果的に車輪の再開発をしてしまった部分もあるかもしれませんが、個人的には良いものが出来たかなと思いました。
今後自分で使っていく中でメンテナンスなどはしていくと思いますが、バグや要望などがあればお気軽にSpellCheckerまで頂ければと思います。
ついでに改めてですが、良かったらスター ください
SpellChecker
振り返ってみるとあまりiOS関係無かったですね。明日は @shtnkgm さんです。