33
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

iOSAdvent Calendar 2019

Day 3

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

Last updated at Posted at 2019-12-03

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 が重たいのが気になった
  • 出力結果の変換が面倒
  • 外部ツールへの依存はあまりしたく無かった
  1. cspellを参考にして単語リストを作成して、リストに無い場合はタイポと見なす方法を検討したが 却下
  • 単語リストが重たい
  • 重たいリストを読み込んでパースする処理も比例して重たい
  • Swift Package Managerではリソースを持つ事が出来なかった
  1. Xcode上で使われる事を想定するとLinuxの事を考える必要が無いなと思い、macOSが持ってる辞書を利用出来ないかを検討したが 却下
  • 精度が悪い(想像以上に辞書に登録されている単語が少なかった)
  • Private APIを利用しないと辞書の選択が出来ない(しかもObjective-Cからしか利用出来ない)
  1. スペルチェックで調べていると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 さんです。

33
18
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?