ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Swiftパッケージ:リソースとローカリゼーション
Swiftパッケージを使ってSwiftコードをシェアする際、リソースも一緒にシェアしましょう。画像やストーリーボードといったアセットをパッケージに含める方法、それらをコードからアクセスする方法をお伝えします。また、ローカライズされたストリングを追加することで、世界中のユーザーがコードにアクセスできるようにする方法をご説明します。このセッションを最大限に活用するには、Swiftとパッケージングコードの知識があることが望ましいです。概略については、WWDC19の"Creating Swift Packages"をご覧ください。
リソース
関連ビデオ
WWDC22
WWDC20
- スケーラブルなエンタープライズAppスイートのビルド
- Swiftの新機能
- Swiftパッケージとしてバイナリフレームワークを配布する
- Xcode PlaygroundにおけるPackageとProject
WWDC19
-
ダウンロード
こんにちはWWDCへようこそ “Swiftパッケージ:リソースとローカライズ” 私はアンダースと申します 今日は Swiftパッケージのリソースと ローカライズについてお話させていただきます まず最初に Swiftパッケージにリソースを 追加する方法を調べてみます それに続いて パッケージが ビルドされたときに何が起こるのか また パッケージ内のコードは 実行時にどのように リソースを利用するのかについて説明します 最後に パッケージ内のリソースをローカライズ する方法についても触れていきます
それでは パッケージへの リソースの追加からスタートします Xcode 11はSwiftパッケージを サポートするようになりましたから あなたのXcodeプロジェクトにすでに 存在するパッケージを利用できるばかりでなく パッケージの作成もできるようになりました パッケージをSwiftばかりでなく 任意のC系言語に実装することができます Xcode 12では 画像やStoryboardなどのリソース 以外の他のファイルも パッケージに追加でき
これらのリソースもローカライズ可能なため 国際化対応アプリケーションは あなたのパッケージが提供する機能を 活用することができます リソースをパッケージに追加する作業では既存の APIを使用できますから あなたのパッケージが OSバージョンに依存する要件を 持っていたとしても影響を受けません
実際どのように機能するのか調べてみましょう ここに SwiftUIビューを 実装したパッケージがあります このパッケージはサイコロの側面を示してて サイコロを回転させるための ボタンが1つあります Xcode 12で新に導入された機能が パッケージが 持つSwiftUIビューをプレビューする機能で これを実行するのに同一ワークスペース内に クライアントアプリケーションは不要です ご覧になると 何かが欠けていることに気付かれるでしょう サイコロ上のドットではなく 黒色のボックスを表示しています ボタンを押してサイコロを回転させようとすると 新しいドットの数を取り込みますが それを表示しません この問題を修正してみます DiceUIターゲットのソースコードの隣に アセットカタログを作成します
Xcodeはファイル名についたサフィックスから これがアセットカタログであることを 認識して その処理方法を知ります 最初 アセットカタログは空になっていますが 私がこれに 数の異なる何種類もの ドットを示す画像を追加します 解像度が3段階に 分かれていることに注意してください
それでは ビューの実装を開始して Rectangleビューを画像で置き換えます
ここでは 画像の名前がドットの数と 一致するように選択してあります したがって 名前を イニシャライザーへ引き渡すだけです
これらの画像が 私のコードが組み込まれた モジュールのリソースバンドルから 来たものであることを示すために 1つのバンドルパラメータを指定します
パッケージリソースは 該当するバンドルタイプの中から 既存のFoundation APIを使用して リソースへアクセスします そのためバンドルパラメータを受け取れる どのAPIへもそれを引き渡すことができます これが一瞬の間にどのように実行されるのか 詳しく見てみましょう ご覧のように サイコロの画像が画面に現れました
“roll”ボタンをクリックすると サイコロ上に表示されるドットの数が変わります ここまでくれば バンドル部分を 削除できるようになります なぜなら Swiftタイプインファレンスでは .moduleしか保持できないからです
ここまで Swiftパッケージへの リソースの追加とプレビューの表示が Xcode上で作業すれば 非常に簡単であることを見てきました パッケージ内のファイルはファイル タイプに応じて処理され それぞれのタイプは ファイル名サフィックスによって識別されます アセットカタログや ストーリーボード Core Dataモデルなど ある種のファイルには 明確な使用目的が存在します Xcodeはこれらのファイルの 処理法を知っていますから 単純にパッケージに追加するだけで十分です
それ以外の種類のファイルは 様々な使用目的を持っことがあります プレインテキストファイルは 実行時に必要となることがありますが 開発時にのみ必要である場合もあります 画像や シェルスクリプト その他の一般的な タイプのファイルについても同じことが言えます
これらのファイルでは そのファイルの使用目的をパッケージ マニフェストの中で宣言しなければなりません 実例を使って調べてみましょう ここに示すのは MyGameと呼ぶパッケージの ファイルシステム構成例です このパッケージは“GameLogic”という名前の 単一ターゲットを持ち すべてのターゲットのソースファイルはSources ディレクトリの下に置かれています このディレクトリは ターゲットと同じ名前を持つ ディレクトリのサブディレクトリの1つです
パッケージマニフェストファイルの 内容を見てみると GameLogicに対応する製品定義と ターゲット定義が書かれています
使用目的が不明瞭な ターゲットファイルがある場合は そのファイルを何に使用するのかを ここに宣言します
パッケージマニフェストの構文と ファイルシステム構成との関係について さらに詳しく知りたいお客様は WWDC 19セッションの “Adopting Swift Packages in Xcode”をご覧ください
ターゲットディレクトリに注目してみましょう すべてのターゲットのソースとリソースが このディレクトリの下に配置されています Swiftのソースファイルも すでにそこに 置かれています パッケージをビルドする際に ソースファイルも一緒にコンパイルする 必要があるからです マニフェストにこれ以外のものは必要ありません それでは アセットカタログを追加しましょう アセットカタログは明確に定義された 構造を持つディレクトリであり ファイルは特定の拡張子を持っています このディレクトリはビルド時に処理されて パッケージのクライアントに含まれます マニフェストに特別なものは必要ありません ストーリーボードを 追加する場合も事情は同じです ストーリーボードも明確な目的を持っており Xcodeプロジェクトに含まれる他の オブジェクトと同じ方法でコンパイルされます
次に プレインテキストファイルを追加しましょう
ここで 話がやや複雑になってきます テキストファイルは多くの異なる目的に 使用される可能性がありますから Xcodeがそれをどのように処理するかは 明らかではありません 実行時に参照するのかも知れませんし 単なる開発時の内部メモなのかも知れません この例で取り扱うのは Xcodeが リソースとして取り扱わないファイルです パッケージのビルド時に 無視されるようにするため このファイルをマニフェストの除外対象 ファイルのリストに追加します
ファイルやフォルダが多数書き込まれた ディレクトリを追加することも可能です たとえばゲームのアートワークを作成するための スケッチや設計ドキュメントが置かれています ファイルを除外リストへ追加するのと同じように マニフェストの除外リストへディレクトリの サブパスを追加することも可能です その下に置かれたすべてのオブジェクトとともに パッケージのビルド時にスキップされます
次に 単独で存在する画像ファイルを 追加してみましょう この場合は 実行時に必要となるファイルですから リソースとしてマニフェストへ追加します このファイルに対する処理操作を指定します
大部分のリソースは ビルド時に適切な形態へ変換するための 処理操作を必要とします 実際に実施される処理の正確なタイプは パッケージをビルドする対象となる プラットフォームに依存します
サンプルゲームが実行時に必要とする多数の ファイルを含むディレクトリを追加してみます このケースでは 問題のディレクトリの下に 階層化されたファイルとフォルダ全体が対象です
ディレクトリ構成を含む すべてが実行時に使用できなければなりません それをリソースとして宣言するのですが 今回は “copy”アクションを指定します これにより ディレクトリ構造を保存しながら 現在の状態が正確にコピーされます
ここまでに 何種類かのファイルをパッケージ ターゲットへ追加する方法を見てきました また ファイルタイプだけからは 用途が分からない場合には 意図を宣言する方法についても調べてきました
これまで見てきたように リソースは処理されることもあり バイト単位でコピーされることもあります 一般的に好ましいのは “プロセス”アクションを選択することです その理由は 対象とするプラットフォーム用に 組み込まれた正しい規則が適用されるからです このプロセスには ストーリーボードやアセット カタログを実行に適した形への変換も含まれます 画像圧縮などの処理も含まれます
ファイルのタイプが分からない場合 または 該当するプラットフォーム向けに 特別な処理を行う必要がない場合 そのファイルはコピーされます
処理規則はディレクトリの下にある すべてのファイルに再帰的に適用され その結果生ずる個々の出力ファイルは 別なリソースとして製品にインクルードされます
“copy”アクションを使用するのが 適しているのは ファイルタイプを問わずに リソースの正確なコピーを作成したい場合です
コピー自体は何の変換操作も行いませんから たとえば 通常であればコンパイルされていたであろう ソースファイルを実行時に テンプレートとして使用したい場合などに コピー機能を使用することができます
ディレクトリ全体を その階層構造を維持しながら インクルードしたい場合にも コピーを使用できます ビルドを実行したとき ターゲット内の ファイルには何が起こるのでしょう? たとえば ここに示すのは1つのパッケージと このパッケージを使用するアプリケーションです このパッケージはリソースファイルばかりでなく ソースファイルも含んでいます 個々のターゲットのソースはコンパイルされて コードモジュールに編入され クライアントアプリケーションにリンクされます 個々のターゲットのリソースは処理されてから 当該モジュールのリソースバンドルに編入され アプリケーションに埋め込まれます
Appleプラットフォームの場合は アプリケーションとアプリエクステンションは バンドルですから それ以上の作業を行う必要はありません 個々のパッケージモジュールに対応する リソースバンドルは アプリケーションバンドルの一部となりますから したがって 実行時に使用することができます
コマンドラインツールのような 非バンドル製品をビルドするときは そのツールに併せてリソースバンドルを インストールすることが必要になります
パッケージバンドルについては あと1つ触れておく必要があります それがミニマムツールバージョンです Swift Package Managerは Swiftツールチェーンの一部です パッケージリソースがサポートされるように なったのはSwift 5.3からですから パッケージマニフェストは 5.3を必要なツールの バージョンとして宣言しなければなりません これとXcodeのバージョンとの関係は どうなるのでしょう?
すべてのリリースのXcodeは いずれかの バージョンのSwiftツールチェインを含みます Swiftパッケージをサポートする 最初のバージョンはXcode 11でした そのときのSwiftツールチェインの バージョン番号は5.1です Xcode 12には Swiftツールチェインの バージョン5.3が含まれています このツールのバージョン番号は パッケージが必要とする機能をサポートする バージョンの中で最も低い番号を 設定しなければなりません そのツールを使用するパッケージやプロジェクト がパッケージを ビルドできるためには そのバージョン以降の ツールを必要とするからです これで リソースをパッケージに追加しましたから 次に コードから リソースへアクセスする方法を説明します これまで見てきたように 実行時にパッケージリソースへアクセスする ためにFoundationのBundle APIを使用します
Foundationは Swiftパッケージをサポートする プラットフォームであれば どのプラットフォームからでも利用できます リソースへアクセスする方法として最も一貫性が あり かつプラットフォーム依存が少ない方法です つまり ビルドシステムが特定のプラットフォーム 上で作成する 特有な生成物の影響を受けません
Xcodeがリソースを内包するパッケージ ターゲットをビルドするとき Xcodeは該当するリソースバンドルのために アクセッサーを生成して それをターゲット向けに作成する コードモジュールへインクルードします 実装に用いたのがSwiftであるか Objective-Cであるかにかかわらず モジュールからリソースバンドルへの アクセスが可能となります
返されるバンドルオブジェクトは それぞれのコードモジュールに固有ですが ソースコードに記述するアクセス方法は 常に同じです
ここに示すのは Bundle APIを使用してリソース バンドル内のファイルにアクセスする例です SwiftとObjective-Cの両方の例を示しています
どちらの言語でもアクセッサーは Foundation Bundleオブジェクトを返し これを使用してリソースを 名前で検索することができます
しかし 任意のシステムAPIを使用してリソース バンドルを引き渡すことも可能です この場合 APIはバンドルを パラメータとして受け取ります
ここに示す例では パッケージリソースバンドルから画像を探索する 機能を持つUI-Imageメソッドへ引き渡しています
リソースをパッケージに追加するときは それを使用するコードモジュールに対応する ターゲットへ追加しなければなりません リソースバンドルアクセッサーは リソースと同じモジュール内の コードのみから認識可能なのです 他のモジュールへリソースを 提供する必要がある場合は 個々のリソースにベンドできるように 特定の型付けを持つ アクセッサーを追加するのが最も良い方法です リソースバンドル全体を 他のモジュールへベンドしようとするのは 一般的にはお薦めできません 何故ならば リソースの名前に関連して 外部との依存関係が発生してしまうからです
Xcode 12 では ローカライズされたリソースを あなたのパッケージに追加することも可能です それでは 前に見たサンプルパッケージ内の テキストのローカライズ方法について説明します
まず最初に デフォルトのLocalizationパラメータを 私のパッケージマニフェストに追加します
これによって 開発中に使用する言語を 宣言するとともに 実行時には より良いマッチングが得られない場合の フォールバックローカリゼーションとしても 使用されます リソースをパッケージを含むのであれば どの場合においてもこれが必要です
私のデフォルトローカリゼーションの英語用に ローカリゼーションディレクトリを作成します
それに“en.lproj”という名前と付けます
そのディレクトリ内に“Localizable.strings” というファイルを作成します
この文字列ファイルに1つの項目を追加します この項目は 私がコード内で使用した ローカライズ文字列キーを Englishの単語“roll”へマッピングします
次に Frenchに対して同じ作業を行います “fr.lproj”という名前のディレクトリを作り その中に“Localizable.strings” ファイルを作成します
このファイルに English文字列キーから
その単語のFrench訳へのマッピングを追加します ここで Imageビューに行ったのと同じ操作を Textビューに対して実施します 具体的には 私のコードを内包するモジュールへ リソースバンドルを引き渡します この作業のために Foundationの ローカリゼーションサポートを使用して ユーザーの選択に対応した正しいローカライズ コンテンツを見つけなければなりません
私のシステム言語はEnglishですから プレビューはまだ英語表示のままです しかし SwiftUIを使用すればプレビューを カスタマイズすることができます たとえば 環境オーバーライドを追加すれば フランス語にローカライズされた プレビューを見ることができます 作成されたリソースバンドルからの ローカライズされた文字列を使用しています
このデモで見てきたように ローカリゼーションディレクトリは“.lproj” というファイル名拡張子を持っています ローカリゼーションディレクトリは マニフェストに記述しなくても パッケージターゲットへインクルード することが可能です なぜならば 拡張子“.lproj”を見れば 目的が分かるからです
通常 ローカリゼーションディレクトリには 文字列ファイルと テキスト翻訳のための 文字列辞書ファイルが置かれています パッケージ内の個々のリソースの カスタム化バージョンが置かれることもあります
アセットカタログのコンテンツを ローカライズすることも可能です 特定のローカリゼーションごとに異なるアート ワークを提示するのが適切と思われる場合は それも可能となります
この作業についてさらに詳しくは WWDC 19の“Creating Great Localized Experiences”セッションを ご覧ください
ローカライズされたリソースを パッケージに追加するときは パッケージマニフェスト内でデフォルト ローカリゼーションを宣言する必要があります
この作業では Appleプラットフォーム上での すべてのローカリゼーションで使用したのと 同じ種類の言語IDを使用するとともに 希望するどの言語も利用できない場合に 代替として使用する言語を指定します
このトピックスについて詳しい情報を ご希望の場合は developer.apple.comにて“Language and Locale IDs”ドキュメントをご覧ください
Swiftパッケージにリソースを追加する方法と Xcodeが実行時にそれらのリソースに アクセスできるようにするリソースバンドルを ビルドする方法を見てきました また パッケージ内のリソースをローカライズする 方法についても調べてきました
Xcodeを使用すればSwiftパッケージを 作成できるばかりでなく 既存のパッケージの日々成長し続ける エコシステムを有効活用することができます Xcode 12を使用すると SwiftUIビューを 内包するパッケージの開発が簡単になります クライアントアプリケーションが存在しなくても あなたのビューと相互作用させられるからです ローカライズされたパッケージリソースへの サポートも強化されていますから 世界中のユーザーニーズに対応できる機能 を備えたパッケージの作成が容易になりました ご覧頂きまことに有難うございました 残りのWWDC 20もお楽しみください
-
-
4:09 - Package Manifest file
// swift-tools-version:5.3 import PackageDescription let package = Package(name: "MyGame", products: [ .library(name: "GameLogic", targets: ["GameLogic"]) ], targets: [ .target(name: "GameLogic", excludes: [ "Internal Notes.txt", "Artwork Creation"], resources: [ .process("Logo.png"), .copy("Game Data")] ) ] )
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。