拡張 SDK でのプログラミング
ユニバーサル Windows プラットフォーム (UWP) アプリがさまざまなクラスのデバイスを最も効果的にターゲットにするWindows 10方法を理解するために、このトピックでは次の概念について説明します。
- デバイス ファミリ
- 拡張機能 SDK
- API コントラクト
また、プログラミングで使用する方法についても説明します。
ビデオ - UWP とデバイス ファミリの概要
デバイス ファミリとアプリのターゲット デバイス ファミリ
デバイス ファミリに基づいて、デバイスのクラス全体で想定できる API、システム特性、動作を特定します。
デバイス ファミリは、オペレーティング システム (OS) の基盤です。 たとえば、PC とタブレットは OS のデスクトップ エディションを実行し、デスクトップ デバイス ファミリに基づいています。 IoT デバイスは、IoT デバイス ファミリに基づく OS の IoT エディションを実行します。
各子デバイス ファミリは、ユニバーサル デバイス ファミリから継承する API に独自の API を追加します。 子デバイス ファミリ内の API の結果の和集合は、そのデバイス ファミリに基づく OS に存在することが保証されるため、その OS を実行しているすべてのデバイスに存在することが保証されます。
アプリの ターゲット となるデバイス ファミリ (またはファミリ) の決定は、ユーザーの決定です。 この決定はこれらの重要な点でアプリに影響します。 これは、次のことを決定します
- Microsoft Store からインストールするためにアプリが提供されているデバイスのファミリ (その結果、アプリの UI を設計するときに考慮する必要があるフォーム ファクター) と
- アプリを実行しているデバイス (ホスト デバイス) に存在する必要がある特定の API セット。
存在することに依存することで、最初にテストを行わずにこれらの API を呼び出して、それらがホスト デバイスに存在するかどうかを確認できることを意味します。 ターゲットとするデバイス ファミリは、その保証を提供します (デバイス ファミリごとに異なる保証)。
ターゲット デバイス ファミリを構成する
アプリ パッケージ マニフェスト ソース ファイル ( Package.appxmanifest
ファイル) では、 TargetDeviceFamily 要素にName 属性があります。 その属性の値は、アプリがターゲットとするデバイス ファミリの名前です。 次の値が有効です。
- Windows.Desktop
- Windows.Holographic
- Windows.IoT
- Windows.Mobile
- Windows.Team
- Windows.Universal
- Windows.Xbox
既定では、UWP アプリはユニバーサル デバイス ファミリを対象とします (つまり、Microsoft Visual Studio では TargetDeviceFamily に指定されていますWindows.Universal
)。 つまり、アプリはすべてのWindows 10デバイスにインストールでき、ホスト デバイスに存在する大規模なコア API セットに依存できます。 このようなアプリは、さまざまなデバイスで実行できるため、高度に適応性の高い UI と包括的な入力機能を備える必要があります。 このトピック で後述する「さまざまな画面サイズで UI をプレビュー する」を参照してください。
Microsoft Store からインストールするためにアプリが提供されるデバイスのファミリを制限する場合は、デスクトップ デバイス ファミリ ()、IoT デバイス ファミリ (Windows.Desktop
Windows.IoT
) など、別のデバイス ファミリを対象にすることを選択できます。 もちろん、アプリをホストできるデバイスは少なくなりますが、それらのデバイスに存在するより大きな API セット (ユニバーサル デバイス ファミリのセットとターゲット デバイス ファミリのセット) に依存できます。 このようなアプリは、通常、中程度のアダプティブである必要があります。特定の種類のデバイスでのみ実行できるため、UI と入力機能に多少特化できます。
ヒント
しかし、あなたは両方の世界の最高を持つことができます。 すべてのWindows 10デバイスで実行するようにアプリを構成したり、特定のデバイス ファミリの特殊な機能にアクセスしたりできます。 このベスト オブ 両方のシナリオでは、少し余分な作業が必要になります。これについては、このトピックの後半でその詳細を説明します。
ターゲット デバイス ファミリのバージョンを構成する
API は時間の経過と同時に Windows に追加されるため、デバイス ファミリを選択するためのもう 1 つのディメンションは、対象となるバージョン (またはバージョン) を決定することです。 Visual Studio の一部のプロジェクトの種類には、ターゲット プラットフォームのバージョンを構成できるプロパティ ページがあります。 ただし、すべてのプロジェクトの種類について、プロジェクト ファイル内でターゲット プラットフォームのバージョンを直接構成できます。
プロジェクト ファイル内の関連プロパティを示す例を次に示します。
<!-- MyProject.Xxxproj -->
<PropertyGroup Label="Globals">
...
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
...
</PropertyGroup>
ビルド時に、これらの値 (からTargetDeviceFamily@NamePackage.appxmanifest
の値と共にAppxManifest.xml
) が、プロジェクトの出力フォルダーに生成されたファイルにコピーされます。 次に例を示します。
<!-- AppxManifest.xml -->
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal"
MaxVersionTested="10.0.19041.0"
MinVersion="10.0.17134.0" />
...
</Dependencies>
MaxVersionTested では、テスト対象のアプリが対象とするデバイス ファミリの最大バージョンを指定します。 また、MinVersion は、アプリが対象とするデバイス ファミリの最小バージョンを指定します。 詳細については、「 TargetDeviceFamily」を参照してください。
重要
これらのバージョン番号は、Visual Studio プロジェクトのプロパティ ページ、またはプロジェクト ファイルの WindowsTargetPlatformVersion と WindowsTargetPlatformMinVersion の値を使用して構成する必要があります。 ビルドによってそのファイルが上書きされるため、編集 AppxManifest.xml
しないでください。 また、アプリ パッケージ マニフェスト ソース ファイル (Package.appxmanifest
ファイル) 内の TargetDeviceFamily 要素の MinVersion 属性と MaxVersionTested 属性は編集しないでください。これらの値は無視されるためです。
拡張機能 SDK とその参照方法
Visual Studio プロジェクトでターゲットをユニバーサル デバイス ファミリから他のデバイス ファミリに変更する場合は、そのデバイス ファミリに対応する拡張 SDK への参照を追加する必要があります。 これにより、そのデバイス ファミリ内の API をプロジェクトで使用できるようになります。
たとえば、IoT デバイス ファミリをターゲットとする場合は、(ソリューション エクスプローラーでプロジェクト ノードを選択した状態で) [プロジェクト>の参照の追加]をクリックします。>ユニバーサル Windows>拡張機能を選択し、UWP 用の Windows IoT 拡張機能の適切なバージョンを選択します。 たとえば、呼び出す最新の IoT API がバージョン 10.0.17134.0 で導入された場合は、そのバージョンを選択します。
この参照は、プロジェクト ファイル内でどのように表示されるかを示します。
<ItemGroup>
<SDKReference Include="WindowsIoT, Version=10.0.17134.0" />
</ItemGroup>
名前とバージョン番号は、SDK がインストールされている場所にあるフォルダーと一致します。 たとえば、上記の情報は という名前のフォルダーと一致します
\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsIoT\10.0.17134.0
その他の拡張機能 SDK には、 UWP 用 Windows デスクトップ拡張機能、 UWP 用 Windows モバイル拡張機能、 UWP 用 Windows チーム拡張機能などがあります。
ユニバーサル デバイス ファミリを対象とするアプリを終了した場合でも、1 つ以上の拡張機能 SDK への参照を追加できます。 呼び出す追加の API が含まれている拡張機能 SDK を参照します。 ユニバーサル デバイス ファミリをターゲットにしているため、存在することに依存できる唯一 の API であることに注意してください。 参照した拡張機能 SDK の API の場合は、呼び出す前に実行時にホスト デバイスに存在することをテストする必要があります (詳細については、このトピックの「 コードの記述 」セクションを参照してください)。 もちろん、ユニバーサル デバイス ファミリの API に対してそのテストを実行する必要はありません。 これは、前のセクションで説明したベスト オブ 両方のシナリオです。
拡張 SDK を使用すると、特定のデバイス ファミリの一意の API をターゲットにして、その特殊な機能にアクセスできます。 対応するデバイス ファミリをターゲットにするかどうかに関係なく、これを行うことができます。
API コントラクトとその検索方法
デバイス ファミリ内の API は、API コントラクトと呼ばれるグループに分割されます。 デバイス ファミリの新しいバージョンがリリースされると、基本的にその新しいバージョンは、そのデバイス ファミリに属するすべての API コントラクトの新しいバージョンのコレクションを表します。
たとえば、 という名前 Windows.Foundation.UniversalApiContract
の API コントラクトは、ユニバーサル デバイス ファミリのバージョン 10.0.17134.0 に付属していたバージョン 6.0 でした。 ただし、同じデバイス ファミリのバージョン 10.0.19041.0 に付属したとき、同じコントラクトはバージョン 10.0 でした。
WinRT API の API コントラクトを検索する
特定のWindows ランタイム API の API コントラクト名とバージョン番号を検索する方法を見てみましょう。 このトピックの後半の「 コードの記述 」セクションでは、その情報を使用する理由と方法について説明します。
最初の例として、 StorageFolder.TryGetChangeTracker メソッドを使用します。 このトピックのWindows 10要件に関するセクションでは、StorageFolder.TryGetChangeTracker が バージョン 6.0 の Windows.Foundation.UniversalApiContract
で最初に導入されたことがわかります。
次に、 StorageFolder.TryGetItemAsync メソッドのトピックを見てみましょう。 そのトピックには、Windows 10要件に関するセクションはありません。 代わりに、 StorageFolder クラス自体のトピックを参照してください。 Windows 10要件に関するセクションには、回答があります。 StorageFolder.TryGetItemAsync トピックでは何の違いも示されないため、その要件を親クラスと共有すると結論付けることができます。 そのため、 StorageFolder.TryGetItemAsync は、 のバージョン 1.0 Windows.Foundation.UniversalApiContract
で最初に導入されました。
ターゲットにするデバイス ファミリを選択する方法
ターゲットとするデバイス ファミリを決定するのに役立つ考慮事項をいくつか次に示します。 詳細については、「 TargetDeviceFamily」を参照してください。
アプリのリーチを最大化する
アプリで最大の種類のデバイスに到達し、その結果、可能な限り多くのデバイスで実行するには、アプリでユニバーサル デバイス ファミリを対象にする必要があります。 具体的には、見てきたように、ユニバーサル デバイス ファミリのバージョンの範囲をターゲットにします。
アプリを 1 種類のデバイスに制限する
さまざまなデバイス フォーム ファクターでアプリを実行したくない場合があります。デスクトップ PC や Xbox 本体に特化している可能性があります。 その場合は、子デバイス ファミリの 1 つをターゲットにすることを選択できます。
アプリを使用可能なすべてのデバイスのサブセットに制限する
ユニバーサル デバイス ファミリをターゲットにしたり、子デバイス ファミリの 1 つをターゲットにしたりする代わりに、2 つ (またはそれ以上) の子デバイス ファミリをターゲットにすることができます。 デスクトップとモバイルをターゲットにすることは、アプリにとって意味がある場合があります。 または、デスクトップとチーム。 または、デスクトップ、モバイル、チームなど。
デバイス ファミリの特定のバージョンのサポートを除外する
まれに、特定のデバイス ファミリの特定のバージョンを持つデバイスを 除く すべての場所でアプリを実行することが必要になる場合があります。 たとえば、アプリがユニバーサル デバイス ファミリのバージョン 10.0.x.0 を対象としているとします。 今後オペレーティング システムのバージョンが変更された場合 (たとえば、10.0.x.2) は、アプリをユニバーサルの 10.0.x.0 と Xbox の 10.0.x.2 に設定することで、Xbox のバージョン 10.0.x.1 を除くあらゆる場所で実行するように指定できます。 その後、アプリは Xbox 10.0.x.1 以前のデバイス ファミリのバージョンのセットでは使用できなくなります。
コードの記述
コードの多くは、すべてのデバイスで同じ方法で実行されるという意味で普遍的です。 ただし、特定のデバイス ファミリに合わせたコードの場合は、アダプティブ コードを使用するオプションがあります。 これらの異なるケースを考えてみましょう。
ターゲット デバイス ファミリによって実装される API を呼び出す
UWP アプリで API を呼び出す場合は常に、アプリが対象とするデバイス ファミリによって API が実装されているかどうかを知る必要があります。 Visual Studio IntelliSense には、ユニバーサル デバイス ファミリの API と、参照した拡張機能 SDK で使用できる API が表示されます。
Windows ランタイム API リファレンス ドキュメントでは、API がどのデバイス ファミリに含まれているかを示しています。 Windows ランタイム API の API リファレンス トピックを調べ、「Windows 10要件」セクションを探すと、実装するデバイス ファミリと、API が最初に表示されるそのデバイス ファミリのバージョンが表示されます。 Windows 10要件セクションがない場合は、メンバーの所有クラスを確認し、そのWindows 10要件セクションの情報を参照してください。 この情報はメンバーにも適用されます。
ターゲット デバイス ファミリによって実装されていない API を呼び出す
参照した拡張 SDK で API を呼び出したいが、その API はターゲットとするデバイス ファミリの一部ではない場合があります。
たとえば、ユニバーサル デバイス ファミリを対象としている可能性がありますが、アプリがデスクトップ デバイスで実行されている場合は常に呼び出すデスクトップ API があります。
または、アプリがデバイス ファミリの初期バージョンをサポートしている可能性がありますが、呼び出す API は、同じデバイス ファミリの最新バージョンでのみ使用できます。
このような場合は、これらの API を安全に呼び出すことができるように、アダプティブ コードを記述することを選択できます。 次のセクションでは、その方法について説明します。
ApiInformation を使用してアダプティブ コードを記述する
アダプティブ コードを使用して API を条件付きで呼び出すには、2 つの手順が必要です。 最初の手順では、API をプロジェクトで使用できるようにします。 これを行うには、API を所有するデバイス ファミリを表す拡張 SDK への参照を追加します。
2 番目の手順では、コード内の条件で ApiInformation クラスを使用して、呼び出す API の存在をテストします。 この条件は、アプリがどこで実行されるたびに評価されます。 ただし、API が存在し true
、そのため呼び出しが可能なデバイスでのみ 評価されます。
少数の API のみを呼び出す場合は、次のように ApiInformation.IsTypePresent メソッドを 使用できます。
// Cache the value, instead of querying it multiple times.
bool isHardwareButtonsAPIPresent =
Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");
if (isHardwareButtonsAPIPresent)
{
Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
}
この場合、 HardwareButtons クラスの存在は、クラスとメンバーの要件情報が同じであるため、 CameraPressed イベントが存在することを意味すると確信しています。 しかし、そのうちに、新しいメンバーは既に導入されているクラスに追加され、それらのメンバーは後でバージョン番号 で導入 されます。 このような場合、IsTypePresent を使う代わりに、IsEventPresent、IsMethodPresent、IsPropertyPresent、および同様のメソッドを使って個々のメンバーの存在をテストすることができます。 次に例を示します。
bool isHardwareButtons_CameraPressedAPIPresent =
Windows.Foundation.Metadata.ApiInformation.IsEventPresent
("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");
ご存知のように、デバイス ファミリ内の API のセットは、さらに API コントラクトと呼ばれるサブ区分に分割されます。 API コントラクトの存在をテストするには、ApiInformation.IsApiContractPresent メソッドを使うことができます。 これは、すべて同じバージョンの API コントラクトに属する多数の API の存在またはその他の方法を知るために、1 つの条件を効率的に実行する方法です。
最初に関心のある API を導入した API コントラクトを確認する方法については、このトピックの前の「 WinRT API の API コントラクトを検索する 」セクションを参照してください。
その情報を取得したら、それをアダプティブ コードにプラグインできます。 たとえば、API コントラクトの名前が で Windows.Devices.Scanners.ScannerDeviceContract
、メジャー バージョン番号とマイナー バージョン番号がそれぞれ 1 と 0 の場合、条件は次の例のようになります。
bool isWindows_Devices_Scanners_ScannerDeviceContract_1_0Present =
Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent
("Windows.Devices.Scanners.ScannerDeviceContract", 1, 0);
さまざまな画面サイズで UI をプレビューする
アプリのリーチを最大化することをお勧めします。 ただし、1 種類のデバイス フォーム ファクターのみを対象とする場合でも、アプリが表示される可能性のある画面のサイズが異なる可能性があります。
アプリがどのように表示され、特定のサイズの画面にレイアウトされるかを確認する準備ができたら、Visual Studio のデバイス プレビュー ツール バーを使用して、小または中のモバイル デバイス、PC、または大きなテレビ画面で UI をプレビューします。 これにより、XAML のアダプティブ レイアウト機能を使用している場合 ( 「視覚的な状態と状態トリガーを含むアダプティブ レイアウト」を参照)、それをテストすることもできます。
サポートするすべてのデバイスの種類について、事前に決定する必要はありません。 プロジェクトには、いつでも追加のデバイス サイズを追加できます。