0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ビルドフェーズ時点でのPreviewによるビルドかどうか検知の試み

Posted at

ビルドフェーズでPreviewによるビルドかどうかを検知したいケースがあったので、そんなことが可能かどうか調べました。

具体的に困ったケース

iOSプロジェクトの開発において、ビルド時にフォーマッターを動作させるRun Scriptを仕込むことケースがあると思います。
しかし、Preview表示時に走るビルドでは開発者によるコードの編集とフォーマッターによるコードの編集がコンフリクトして、Xcodeのアラートが出る場合が結構ありました。
Previewのユースケースとして、Previewを見ながらViewを実装して実装結果のフィードバックを高速に得るというところが代表的なものかと思うので、この事象に困らせられる人は結構多いと思います。
そのため、ビルド時にフォーマッターの実行を仕込んでいるプロジェクトでは、Preview時はフォーマッターを実行しないように条件分岐を入れたいというニーズが生まれました。

検知する方法

ググってすぐ出てきた方法としては、ビルド時に自動で設定されるENABLE_PREVIEWSという環境変数を参照するものです。

Run Scriptでの使用例は、以下のような感じです。

if [ "$ENABLE_PREVIEWS" = "NO" ]; then
    // フォーマット処理を行う
    echo "run format"
else
    echo "skip format"
fi

Previewでのビルド時はENABLE_PREVIEWSに"YES"が入りそうでなければ"NO"と入ります。

注意点

上記方法でいいじゃんと思ってしまいますが、この方法は、Legacy Previewモードでしか使用出来ません。

Previewのモードが、Legacyかどうかを判断するには、Preview表示中にXcodeの上タブから
Editor→Canvas→Use Legacy Previews Executionにチェックが付いているかどうかで判断できます。
チェックがついていれば、Legacy Previewモードです。

Legacy Previewでは静的なライブラリ(Static Libraly, Static Framework)内でのPreviewに対応してなかったり、パフォーマンスの向上がされているとXcode16のリリースノートには記載されています。
また、Legacyとついているだけ合って、いつかは足が切られてしまい使用出来なくなる可能性もあるので長期的な目線では、上記の方法でPreviewによるビルドかどうかの検知を行うのは、よくなさそうです。

Xcode16からは、デフォルトではUse Legacy Previews Executionにチェックがついていません。

新しいPreviewモードでビルドフェーズ時点でのPreviewによるビルドかどうかの検知方法

これは調べてみましたが、無いようです。
AppleのDeveloper Forumにてそれが語られていました。

Appleのエンジニアの回答としては、短期的な対策としては、Use Legacy Previews Executionにチェックをつけることだそうです。

If you want to workaround this in the short term, as you've identified, you can toggle back on the legacy execution mode all the time by opening a source file with a preview, then toggling the "Editor > Canvas > Use Legacy Previews Execution" menu item. This setting is per-project and only persists for that particular version of Xcode. This is meant as an escape hatch while we work out any issues in the new mode.

Appleのエンジニアから中長期的な解決策の言及は見つけられなかったですが、打てる手としては以下になると思います。

1. Preview専用のターゲットを用意して、そのターゲットではフォーマッターのRun Scriptを省く

アプリケーションターゲットとは別にPreviewを実行する用にUIだけを切り出したターゲットを作り、Preview用のターゲットにはフォーマッターのRun Scriptを入れないようにし、Preview実行時にはPreview用のターゲットのスキーマを指定するようにすれば新しいPreviewでも、課題は回避できそうです。

ただ、フォーマッターの競合問題に対して、マルチモジュール化というアプローチはかなりコストが高くオーバーエンジニアリングにもなりかねないとも思います。

2. ビルドフェーズでのフォーマッターをやめる

ビルド時にフォーマッターの処理を行なわずとも、git hooksによりコミットのタイミングでフォーマッターを行うこともでき、リポジトリに管理するコードをもれなくフォーマット済みのコードにするという観点でいれば、ビルド時に実行するよりもこちらの方が確実なので、ビルドフェーズで無理してフォーマッターを起動させる必要はないようにも思えました。

結論

個人的には、短期的にはLegacyを使ってPreviewによるビルドかどうか検知を行いつつ、
中長期的には、上記で記載した「ビルドフェーズでのフォーマッターをやめる」の案が良いかなと思いました。
ただ、もし中長期的にそもそも依存関係が多すぎてPreviewの起動が遅すぎる問題も併発するようなら、その問題も解消できる「Preview専用のターゲットを用意して、そのターゲットではフォーマッターのRun Scriptを省く」という案も検討できるとも考えています。
この辺りの判断は、現在のプロジェクトの状況によりまちまちかと思いました。

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?