Help us understand the problem. What is going on with this article?

XcodeにWarningやErrorを好きな所に表示したい #Xcode #typo #spellchecker

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に記入するだけでワーニングとエラーが表示されます。

スクリーンショット 2019-11-24 18.19.51.png

ファイル指定

# warning
echo "/path/to/your/file: warning: some warning message"
# error
echo "/path/to/your/file: error: some error message"

これだけでファイルを指定してワーニングとエラーが表示されます。

スクリーンショット 2019-11-24 18.21.45.png

行数と文字の箇所指定

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"

と指定すれば該当の行数と文字の箇所にワーニングとエラーが表示されます。

スクリーンショット 2019-11-24 18.24.23.png

尚、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

これでコードを適当に変更してビルドすると

screenshot.png

こんな感じでwarningが表示されるのでどこでタイポしているかが一目瞭然になります。

良かったらスター :star: ください :thumbsup:
SpellChecker


開発にあたって考えた事など

typoを検知する仕組みについて

いくつか検討・実装をしてみて一番簡単でコストの掛からない方法を模索していました。
ざっと以下の様な感じです。

  1. ツールからcspellをそのまま呼ぶ事を検討したが 却下
    • cspell が重たいのが気になった
    • 出力結果の変換が面倒
    • 外部ツールへの依存はあまりしたく無かった
  2. cspellを参考にして単語リストを作成して、リストに無い場合はタイポと見なす方法を検討したが 却下
    • 単語リストが重たい
    • 重たいリストを読み込んでパースする処理も比例して重たい
    • Swift Package Managerではリソースを持つ事が出来なかった
  3. Xcode上で使われる事を想定するとLinuxの事を考える必要が無いなと思い、macOSが持ってる辞書を利用出来ないかを検討したが 却下
    • 精度が悪い(想像以上に辞書に登録されている単語が少なかった)
    • Private APIを利用しないと辞書の選択が出来ない(しかもObjective-Cからしか利用出来ない)
  4. スペルチェックで調べているとUITextCheckerというものを発見し、iOSにあるならmacOSにもあるだろと調べていたらNSSpellCheckerを発見し良さそうだったので 採用 :tada:
    • 逆に精度が高すぎて hogefuga などがタイポにならないのが少し気になる
    • 運用する中で検討していきたい

補足(謝辞)

ちなみに、念の為、他にも同様のツールが無いか簡単に調べた上で作ったんですが、上記の NSSpellChecker の使い方を調べている中で @ezura さんの ezura/spell-checker-for-swift を発見しました。
完全に用途も被っており途中で作るのを諦めるか悩んだのですが、ezuraさんの方がSwiftSyntaxを利用している事を発見し、Swiftファイルに限定された用途なのだと理解しました。
僕の方はあえてSwiftSyntaxを利用せず、半角英字を見つけたらスペルチェックをする様にしているので特にファイル形式を問わない様に作っています。
どちらが良い・悪いというものでもなく、用途に合わせて良いなと思った方を使って頂ければと思います :pray:
尚、 NSSpellChecker の使い方はとても参考にさせて頂きました。ありがとうございました :bow:

まとめ

Advent Calendarドリブンで色々調べたり開発をしたりしてたのですが、結果的に車輪の再開発をしてしまった部分もあるかもしれませんが、個人的には良いものが出来たかなと思いました。
今後自分で使っていく中でメンテナンスなどはしていくと思いますが、バグや要望などがあればお気軽にSpellCheckerまで頂ければと思います。
ついでに改めてですが、良かったらスター :star: ください :thumbsup:
SpellChecker

振り返ってみるとあまりiOS関係無かったですね。明日は @shtnkgm さんです。

fromkk
iOSアプリエンジニアです。 # Type( https://type-markdown.app )やPity( https://freetimepicker.firebaseapp.com/ )というMarkdownエディタアプリを個人的に開発しています。
http://fromkk.me/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした