ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Swift Packageプラグインの紹介
Swift Packageプラグインを使用して、SwiftパッケージやXcodeプロジェクトでアクションを実行する方法をご覧ください。このプラグインが機能する仕組みをはじめ、これを使用してソースコードを生成したり開発ワークフローを自動化したりする方法について解説します。
リソース
関連ビデオ
WWDC23
WWDC22
WWDC19
-
ダウンロード
♪ 落ち着いた雰囲気のヒップホップ音楽 ♪ ♪ こんにちは Andersです このビデオでは Swift package プラグインの 使用方法をご紹介します Swift Packages はXcode 11で発売されました ライブラリをソースコードとして 配布するためのすばらしい方法を提供します Xcode 14ではこの方法が 開発ワークフローに拡張され プラグインを使用してビルド中の ソースコードの生成や タスクリリースの自動化などが行えます このプラグインの内容がどういうもので どう機能するかを説明し Xcode 14でサポートされる コマンドプラグインと ビルドツールプラグインの 2つのパッケージプラグインをご紹介します まずプラグインとは何か パッケージプラグインはSwiftスクリプトで SwiftやXcodeでアクションを実行できます プラグインは Xcodeがこの目的のために 提供するAPIを使用します これはSwift Packageとして実装されます プラグインとライブラリ 実行ファイルが含まれるか プラグインだけを含むこともできます パッケージプラグインは複数の ソースファイルで実装することができます Swift packageは複数の プラグインを定義できます 高度に専門的なプラグインは 提供するパッケージ専用にでき その場合パッケージ内のみで使用できます しかし一般目的のプラグインは パッケージ製品と定義すれば 利用可能にできます パッケージが他のパッケージからの ライブラリを使用できるように 他のパッケージも使用することができます しかしライブラリとは異なり プラグインでの依存関係は Appにランタイムコンテンツを提供しません 代わりに自身のマシンか ビルド自動化で実行する 開発ツールへのアクセスを許可します パッケージプラグインは どんな作業をするのでしょう Xcode 14には2種類のプラグインがあります コマンドプラグインと ビルドツールプラグインです コマンドプラグインはいつでも実行できる カスタムアクションを実装します ソースコードフォーマッタや リンタで実行できます または開発ワークフローの 一部として他のタスクを実行できます それには寄稿者リストの更新や 履歴に基づいた著作権の日付の更新 または引数スクリプトの 作業なども実行できます 必要に応じてコマンドプラグインは パッケージのファイルの 変更の許可を要求できます コードの編成に特に便利です すべてのコマンドプラグインに 書き込み許可は必要なく コマンドによっては変更の必要がなく レポート作成やメトリクスの計算が行えます ビルドツールプラグインは依存性グラフを拡張 ビルドの一部としてソースコードや リソースの生成に特に役立ちます 一度にパッケージ全体やプロジェクトを 呼び出すコマンドプラグインとは異なり ビルドツールプラグインは 各目標に適用されます Xcodeでコマンドプラグインを 使用してみましょう これはiOS Appで さまざまな幾何学的形状を示すものです Appプロジェクトやローカルパッケージからなり パッケージは Appのコアデータ型とロジックを 提供するライブラリを実装します 他の人が使用できるようにパッケージを各自の リポジトリに分割しようと思います その一部としてこのパッケージのコードに 寄稿した全員のリストを作成しようと思います カスタムスクリプトでこれを行えますが コードで作業するのに便利なプラグインを 提供するパッケージがあるのを知っています それに私が望むプラグインがあるはずです このプラグインにアクセスするには 他のパッケージからライブラリを得るように ローカルパッケージのマニフェストに パッケージの依存関係を追加します マニフェストを保存すると 遠隔パッケージがフェッチされ Package Dependenciesに表示されます SwiftFormatもフェッチされています コードの編集で人気のツールです ユーティリティパッケージの コマンドプラグインが SwiftFormatに依存関係を持ったからです この依存関係を追加したところで パッケージが提供するプラグインコマンド すべてにアクセスできます コマンドしたいパッケージの コンテキストメニューを使用します メニューに3つの新しいコマンドがあります SwiftFormatを使用する再編集用ソースコード 他の2つでは特別なアクションを実行できます 1つは寄稿者リストをGitの寄稿履歴に基づき 作成・生成するもので もう1つは私のソースファイルの 著作権日付を更新するものです ここでは真ん中のコマンドを使用します プラグインコマンドを呼び出すと Xcodeはプラグインに パスするターゲットを選択させてくれます ここではパッケージ全体を呼び出します プラグインがカスタム引数を取り入れるなら それらもここでパスします 「Run」をクリックするとプラグインが ファイルシステムを変更するので Xcodeは警告を発します プラグイン作成者が私のコードを変更したい 理由を確認できますが プラグインの実装も見てみたいので 「Show Command」を選択しコードに移動します
このプラグインのアクションは安全です コマンドをもう一度呼び出し 次は「Run」を選択します
Xcodeに私が選んだ プラグインを覚えてもらいます この特定のプラグインはGit履歴を使用して 寄稿者の名前を含んだ ファイルリストを生成します しかし他にもさまざまな機能があります Xcodeでコマンドプラグインを使用したので 次はプラグインの仕組みを 詳細に見てみましょう パッケージプラグインはSwift スクリプトで 必要な時にコンパイルされ実行されます それぞれが個々のプロセスとして実行され プラグインはソースファイルを含む 蒸留された入力パッケージにアクセスでき また パッケージの依存関係に関する 情報も得ます 多くのプラグインは作業の一般として コマンドプラグインを呼び出します プラグインはファイルや ディレクトリを作成でき Foundationなど標準ライブラリを使い 他の作業を実行できます プラグインはサンドボックスで実行し ビルド出力ディレクトリなど ファイルシステムで 書ける場所は限られています しかしコマンドプラグインはパッケージソース ディレクトリでファイルの変更を要求でき ユーザが承認するとこれらのロケーションで 書けるようサンドボックスが構成されます プラグインは結果をXcodeに返すこともでき 警告やエラーを発すこともできます ビルドツールプラグインは 実行中に ツールの呼び出しを定義することができます すべてのプラグインはXcodeが提供する PackagePluginモジュールのAPIを使用します このAPIはプラグインの 入力 パッケージへのアクセスを許可し 適切であれば結果をXcodeに返します プラグインを実装するメインソースファイルも メインエントリポイントを定義します これはプロトコルに適合し プラグインの型に一致する class または structである必要があります Xcodeが呼び出す特定のエントリポイント関数は プラグインの種類によって異なります PackagePlugin APIの詳細については 『Swift Packageプラグインを作成する』 先程コマンドプラグインを使用して パッケージに変更を行いました コマンドプラグインの詳細を見てみましょう コマンドプラグインは 開発 ワークフローを拡張します ビルド中ではなくパッケージに 直接適用されます ファイルシステムを変更しないものもあります ファイルにいかなる変更を加えない 便利なアクションがあります しかしコマンドが ファイル システムに書きたい場合 プラグインを実装した パッケージのマニフェストに 宣言する必要があります これにより Xcodeは プラグインが実行される前に ユーザに許可をリクエストします プラグインは通常小型で 実際の作業を行うには他のツールに依存します 先程プラグインの1つが実際の仕事のすべてに SwiftFormatを使用していましたね ツールパッケージの依存関係は バイナリまたはソースコードになります Xcodeはコマンドが呼び出される前に ソースから必要なツールを作成します プラグインは依存するツールではなく 他のパッケージから提供される場合もあります コマンドプラグインの実装では メイン型はCommandPluginプロトコルに適合し プラグインはperformCommand エントリポイントを実装します このエントリポイントはコンテキストと ユーザが提供した引数を取り入れます コマンドプラグインを 別の方法で呼び出しましょう また同じプロジェクトを使い SourceCodeUtilitiesパッケージに 依存関係を追加しているので ターミナルの同じプラグインを呼び出します まずディレクトリをCoreLibsパッケージに 変えますこのパッケージに コマンドプラグインを適用したいからです Package Manager 5.6には 新しいサブコマンドがあり 「swift package plugin --List」と入力して 利用可能なプラグインを探します Xcodeのメニューと同じ プラグインが表示されました このコマンドラインでは各コマンドが 実行するための動詞を表示しています Xcodeでやったように寄稿者リストの 「再生」という動詞を選択します プラグインはファイルを作成するため 入力の許可をリクエストしています 「yes」を入力して許可し プラグインが実行してリストを更新します 許可を必要とせずプラグインが ファイルシステムに書くことができる パッケージマネージャを使うこともできました これはCIシステムや他のビルド自動化から 呼び出す場合に便利です しかしそのオプションを 使用する前に プラグインの 作業内容を把握してください Xcodeと同じように コマンドライン引数をプラグインにパスします プラグインの動作動詞の後の引数は プラグインにパスされます この場合詳細フラグをパスして プラグイン実行中の出力を確認します 各コマンドプラグインはその引数を定義します コマンドラインプラグインだけでなく ビルドツールプラグインについても お伝えしたいことがあります コマンドプラグインとは異なり ビルドツールプラグインは 即座に作業を行いません 代わりにパッケージが構築された後でXcodeが 実行されるようにビルド ツールを呼び出し変換します 各ツールの呼び出しには 実行のコマンドラインがあり Xcodeに実行することを伝える 入力と出力があります ビルド中やビルド前に実行する コマンドを定義できます 違いはこの後すぐにお見せします
ビルドツールプラグインが 返したコマンドは通常 漸進的なビルドで持続できるよう ビルドディレクトリに 出力を書くよう構成されます プラグインのように ビルドツールプラグインが定義したコマンドは サンドボックスで実行され ネットワークアクセスや パッケージの変更を防止します ビルドツールプラグインの実装では メイン型は BuildTool Plugin プロトコルに適合し プラグインはcreateBuildCommandsを 実装します このエントリポイントは ビルドコマンドの作成に コンテキストとターゲットを取り入れます パッケージが構築された時に実行されるべき カスタムビルドコマンドを返還します ビルドツールプラグインが返還する 基本的なコマンドが2つあります Ordinaryビルドコマンドは 入出力のパスを指定し 出力が見つからない場合や 入力が変更された場合のみ 実行します Prebuildコマンドはビルド開始前に実行し 出力名が事前にわからない場合に 使用することもできます Prebuildはすべてのビルド前に実行するので 変化がない場合は作業を最小限に 抑えてください ビルドコマンドとプリビルドコマンドは ソースコードやリソースの生成に最適です ではXcodeはどのようにプラグインを選択して パッケージターゲットに適用するのでしょうか SwiftPM 5.6 以降では パッケージマニフェストに 新しいプラグインパラメータがあり ターゲットが望む プラグインをリスト付けします このパラメータはターゲットが必要とする ビルドツールプラグインを指定し ランタイムライブラリが依存するように これらのプラグインは同じパッケージにも 別のパッケージにも存在できます Xcodeに戻りましょう 私の図形描画Appで ビルドツールプラグインを使用してみます この特定の場合では Core Libraryターゲットの データファイルに基づいて Swiftコードを生成する コマンドラインツールがあり 具体的な内容は重要ではありませんが 最終的に求めているのは それぞれのデータに対する 生成された型安全のSwift アクセサです データファイルに加えカスタムツールを使用し リポジトリにあるソースコードを生成します このツールを手動で実行し Swiftラッパーコードを再生しデータファイルが 変更するたびに変更を寄稿してきましたが ビルドツールプラグインで さらにいい仕事ができます ビルド中にコードを生成し リポジトリにそのコードが 保管されないようにします
プラグインにアクセスします パッケージマニフェストで 使用したいソース生成プラグインを提供する パッケージに依存関係を作ります
これでパッケージのターゲットは ビルドツールプラグインにアクセスできます
プラグインの使用が必要なターゲットで 定義にプラグインパラメータを追加します
これでXcodeに その パッケージの到底なツールを ターゲットに適用することが伝わります これでリポジトリから 生成されたソースファイルを 削除できるようになりました 必要に応じてビルド中に作成・更新が可能です
これでわかりやすくなりました Appを構築して実行すると ビルドツールプラグインは データファイルが変更するたびにXcodeに コード生成ツールを呼び出すよう要求します 生成されたコードはビルドフォルダで 他のビルドファイルと共に保管され リポジトリはきれいに整理されます このビデオではSwiftパッケージの プラグインとは何か そして 機能について説明しました コマンドプラグインと ビルドツールプラグインの 類似性と相違性について 説明しました どちらのプラグインも さまざまな無作為のスクリプトを より構造的な拡張機能に 置き換える能力があります ビルドツールプラグインは ソースやリソースの生成 またはビルドの一部として その他のカスタム動作が できるよう拡張してくれます コマンドプラグインは一般的な開発タスクを カスタムアクションで自動化してくれます どちらも特定のワークフローに最適で 広範囲のケースで書くこともできます パッケージプラグインの作成方法については 『Swift Packageプラグインを作成する』を ご覧ください ご清聴ありがとうございました ♪
-
-
import PackagePlugin @main struct MyPlugin: ... { // Entry points specific to plugin capability. These entry points are invoked // when the plugin is applied to a package. } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: ... { // Entry points specific to plugin capability. These entry points are invoked // when the plugin is applied to an Xcdeo project. } #endif
-
8:33 - Structure of a command plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin @main struct MyPlugin: CommandPlugin { /// This entry point is called when operating on a Swift package. func performCommand(context: PluginContext, arguments: [String]) throws { debugPrint(context) } } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: XcodeCommandPlugin { /// This entry point is called when operating on an Xcode project. func performCommand(context: XcodePluginContext, arguments: [String]) throws { debugPrint(context) } } #endif
-
11:13 - Structure of a build tool plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin @main struct MyPlugin: BuildToolPlugin { /// This entry point is called when operating on a Swift package. func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] debugPrint(context) return [] } } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: XcodeBuildToolPlugin { /// This entry point is called when operating on an Xcode project. func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] debugPrint(context) return [] } } #endif
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。