次の方法で共有


Windows ストア

OneDrive を Windows ストア アプリに統合する

Tony Champion

コード サンプルのダウンロード

現在では、クラウド開発について議論しないで成功を収めることはできません。クラウド サービスは、パブリック、プライベート、オンプレミス、オフプレミスなど、あらゆる形態とサイズで提供されています。しかし、消費者向けのユーザー ファイル操作アプリについて話題にするときは、Microsoft OneDrive のようなサービスに着目することになります。

Microsoft OneDrive (最近名称が変更されました) を使用すると、ユーザーは場所やデバイスを問わず、自分のファイルを保存、共有、利用できます。OneDrive はすべてのマイクロソフト プラットフォームに完全に統合されるようになり、現在使用されている他のプラットフォームの大半と互換性があります。さまざまなデバイスから、ドキュメント、写真、ビデオなどのファイルを簡単に共有、同期、および使用できます。そのため、ユーザー ファイルを操作するアプリを作成する場合は、OneDrive の統合が重要な機能になります。

Windows ストア アプリをビルドしている場合、OneDrive のある程度の機能が自動的に無料で提供されます。Windows 8.1 には、Windows ストア OneDrive アプリがインストールされるほか、ファイル オープン ピッカー コントラクトやファイル保存ピッカー コントラクトを実装したファイル システムがデスクトップに統合されます。つまり、アプリでファイル オープン ピッカーやファイル保存ピッカーを使用すると、ユーザーは自身の OneDrive アカウントでドキュメントを開いたり保存する機能を自動的に利用できます。デスクトップ アプリのファイルを開くダイアログや保存ダイアログに関しても、同じことが当てはまります。

では、こうした操作の動作をさらに制御するにはどうすればよいでしょう。ユーザーのデータを異なる形式で表示したり、バックグラウンドで複数のファイルのアップロードやダウンロードを処理するには、どうすればよいでしょう。そのようなシナリオに対処するため、マイクロソフトでは、任意のプラットフォームからアクセスして、開発者が OneDrive をソリューションに統合できる API を用意しています。今回はこの API について説明し、Windows ストア アプリからこの API を使用する手順を紹介します。

Live SDK の概要

OneDrive のコンテキストへのアクセスには Live SDK を使用します。Live SDK は、根本的には、任意のプラットフォームで使用できる JSON ベースの REST API のコレクションです。Live SDK では、Windows ストア アプリと Windows Phone ストア アプリに関してはシングル サインオンを使用し、その他のプラットフォームに関しては OAuth 2.0 認証を使用します。開発者が OneDrive を使用して優れたアプリを作成できるよう、マイクロソフトはクライアント固有の SDK もリリースしています。現在、Microsoft Windows および Windows Phone プラットフォーム向け SDK の他に、Android 向け SDK と iOS 向け SDK が用意されています。これらすべての SDK へのリンクは、msdn.microsoft.com/onedrive/dn630256 にあります。Live SDK は NuGet (nuget.org/packages/LiveSDK、英語) を通じて追加することもできます。

OneDrive に関する Live SDK の主な役割は、ユーザーのアカウントを使ってファイルやフォルダーにプログラムからアクセスできるようにすることです。SDK が提供する基本サービスは次のとおりです。

  • フォルダー階層の移動
  • 新しいフォルダーの作成と削除
  • フォルダーのプロパティの読み取りと変更
  • ファイルのアップロードとダウンロード
  • ファイルのプロパティの読み取りと変更
  • ファイルやフォルダーのコピーと移動
  • ファイルやフォルダーを共有するためのリンクの取得
  • フォルダーやファイルのアクセス許可の設定

それでは、XAML で記述された Windows 8.1 ストア アプリで SDK を使用する方法について、Visual Studio 2013 Update 2 と Live SDK バージョン 5.6 を使用して説明します。大半のプラットフォームでクライアント固有 SDK を使用できるので、ここで示す考え方をお使いの言語とプラットフォームにも簡単に当てはめることができます。

Live SDK によるアプリの開発

Live SDK を使用してアプリ開発を始める前に、ちょっとした注意事項をいくつか説明しておきます。Live SDK は Windows のコア SDK に含まれないため、開発者が Live SDK をダウンロードして、アプリから SDK への参照を追加する必要があります。参照を追加するには、Visual Studio 2013 でソリューションを右クリックして、[参照の追加] をクリックします。Live SDK は参照マネージャーの Windows 8.1 の [拡張] セクションにあります (図 1 参照)。

Live SDK への参照を追加する
図 1 Live SDK への参照を追加する

Windows 8.1 ストア アプリでは、appxmanifest でインターネット (クライアント) 機能が既定で有効になっています。これは、Live SDK を使用する場合には必須で、開発するプロジェクトでもこの機能を有効にする必要があります。この機能を確認または有効にするには、プロジェクトの appxmanifest をデザイナーで開いて、[機能] タブの [インターネット (クライアント)] がオンになっていることを確認します。

Live SDK をプロジェクトに追加すると、SDK 全体が Microsoft.Live 名前空間で示されます。ただし、この時点で SDK を使用すると、null オブジェクト参照エラーが発生します。これは、Live サービスにアプリを登録しないと OneDrive にアクセスできないのが原因です。開発するプラットフォームによって、登録の方法はいくつかあります。Windows ストアの場合、アプリを Windows ストアに関連付けるだけです。Visual Studio のウィザードを使用すれば、最も直接的に関連付けを行うことができます。

ウィザードを起動するには、ソリューション エクスプローラーで Windows ストア プロジェクトを右クリックし、[ストア]、[アプリケーションをストアと関連付ける] の順にクリックします。ウィザードが開き、続行に必要な操作の説明が表示されます。[次へ] をクリックすると、Windows ストアに関連付けられる Microsoft アカウントへのサインインを求められます (まだサインインしていない場合)。アカウントに関連付けられた電話番号で認証コードをテキスト メッセージとして受け取るなど、2 つ目の確認プロセスを求められる場合もあります。サインイン プロセスが完了すると、アカウントに関連付けられている予約済みのアプリ名すべてが一覧されます (図 2 参照)。新しいアプリの場合、この画面で新しいアプリ名を予約することもできます。アプリに関連付ける名前を指定して、[次へ] をクリックすると、サマリ画面が表示されます。[関連付け] をクリックするとプロセスは完了です。

予約した名前をアプリに関連付ける
図 2 予約した名前をアプリに関連付ける

これで、アプリが設定され、Live SDK を使用する準備が整います。

ユーザーのデータへのアクセス

OneDrive とアプリの統合を実現する最初の手順は、ユーザーの情報にアクセスできるようにすることです。既に述べたように、Live SDK では 0Auth 2.0 を使用して認証します。ただし、単純にアプリを認証するだけでなく、別に検討することがいくつかあります。

OneDrive の適切な使用: Windows ストア アプリの開発と配置に詳しい方は、アプリ内で可能/不可能なことについての詳細を記載したガイドラインが多数あることをご存知でしょう。これに加えて、OneDrive 固有のガイドラインについても考慮が必要になります。

ガイドラインが定められている主な理由は、OneDrive に対するユーザーからの信頼を損なわないためです。ユーザーが自身の個人情報を保存するためのセントラル ソースを利用する場合、ユーザーはそのソースを根本から信頼するか、そのソースを使用しないかのどちらかです。アプリから OneDrive にアクセスする場合は、ユーザーはその信頼をアプリにまで拡げることになります。そのため、アプリがユーザーの許可なしに、またはユーザーの知らないところでユーザーのデータを削除すれば、その信頼を損なうことになります。また、アプリに対するユーザーの印象が悪くなるだけでなく、OneDrive への印象も悪くなります。このため、アプリから OneDrive を操作する方法には細心の注意が必要です。ユーザー情報の更新や削除を行う機能には特に注意します。このガイドラインの詳細については、bit.ly/1rQ8iXK (英語) を参照してください。

シングル サインオンの使用: マイクロソフトは、Windows ストア アプリで Live SDK を使用する場合に、シングル サインオン (SSO) 機能の活用を推奨しています。Live SDK と同様、アプリに SSO を追加する場合には、プライバシーに関する説明やアカウント設定パネルなどのいくつかの追加要件があります。必要なコンポーネントをアプリに追加する手順の詳細は、bit.ly/TJvTxB を参照してください。

アプリで SSO の準備ができたら、LiveAuthClient クラスのインスタンスを使用してユーザーのアカウントへのログインを行います。LiveAuthClient には、現在 Windows 8.1 デバイスにサインインしている Microsoft アカウントの資格情報を使用する LoginAsync メソッドがあります。サインインが正常に完了した場合、返される LiveLoginResult オブジェクトには LiveConnectSession インスタンスが含まれます。このインスタンスを、すべての Live SDK 呼び出しに使用します。以下のコードでは、ユーザーのログインを処理して Session オブジェクトを返します。

LiveAuthClient authClient = new LiveAuthClient();
LiveLoginResult authResult = 
  await authClient.LoginAsync(new List<string>() {
  "wl.signin",
  "wl.basic", "wl.skydrive", "wl.skydrive_update" });
if (authResult.Status == LiveConnectSessionStatus.Connected)
{
  // Add code to handle session held in the Session property
}

スコープ: 上記のコードで、"wl.signin" のようなスコープを使用しているのがわかります。アプリからユーザーのアカウントにログインする際に、このスコープを使って必要なアクセス許可の種類を特定します。アクセス許可を要求していない部分の API を使おうとすると失敗します。これは、Windows ストア アプリで、パッケージの appxmanifest の [機能] セクションでアクセス許可を要求していない部分の Windows SDK を使用すると失敗するのとまったく変わりません。

今回の例で使用するスコープは 4 つのみです。wl.signin スコープは、Windows ストア アプリで使用する SSO 動作の利用を許可します。wl.basic スコープは、ユーザーに関するいくつかの一般的な情報にアクセスできるようにします。

OneDrive アプリ用に追加され、考慮する必要があるスコープは、wl.skydrive と wl.skydrive_update の 2 つだけです。名前から想像できるように、wl.skydrive はユーザーの OneDrive アカウントの読み取りアクセスと参照アクセスに不可欠です。ファイルのアップロード、フォルダーの作成や削除、オブジェクトのプロパティの変更などの機能が必要な場合は、wl.skydrive_update スコープを使用します。このスコープも開発者に OneDrive の読み取りアクセス許可を提供します。そのため、アクセス一覧に wl.skydrive スコープと wl.skydrive_update スコープの両方を含める必要はありません。

以前のブランド名を使用しているアプリとの下位互換性を維持するために、OneDrive のスコープ名は変更されていません。ただし、この API の今後のバージョンで、OneDrive ブランドを使用した追加のスコープがいくつか登場しても不思議はないでしょう。

Live SDK は OneDrive 以外のさまざまな用途にも対応しているため、ここでは説明していないその他のスコープが数多くあります。スコープの一覧とその説明については、msdn.microsoft.com/library/dn631845 (英語) を参照してください。

ユーザーの同意を得る: OneDrive アカウントへのアクセス許可を要求するアプリをユーザーが初めて実行すると、ログイン呼び出しで指定したスコープのアクセス許可をそのアプリに与えるようユーザーに同意を求めます。図 3 は Windows ストア アプリに表示されるプロンプトの例です。ユーザーがアクセス許可を与えると、スコープのリストを変更しない限り、再びプロンプトが表示されることはありません。更新したバージョンのアプリで API の追加機能を要求すると、再度アクセスを許可する同意をユーザーに求めます。

OneDrive へのアクセスについての同意をユーザーに求める
図 3 OneDrive へのアクセスについての同意をユーザーに求める

OneDrive のオブジェクト

OneDrive API はすべてをオブジェクトと見なします。フォルダー、写真、スプレッドシートなど、OneDrive に保存されたものにはすべて、よく似た一連のプロパティが設定され、API 呼び出しを共有します。各オブジェクトにはプロパティのコレクションがあり、場合によっては子オブジェクトのコレクションもあります。今回取り上げるオブジェクトの種類は、Folder、File、Album、および Photo です。使用できるオブジェクトのリストと、その説明と使い方については、msdn.microsoft.com/library/dn631843 (英語) を参照してください。

アプリで LiveAuthClient の LoginAsync メソッドから LiveConnectionSession のインスタンスを取得した後、そのセッション インスタンスを使用して LiveConnectClient クラスのインスタンスを作成します。このクラスには、OneDrive の操作に使用するすべての API 呼び出しが含まれます。次の例に、LiveConnectClient インスタンスの作成と OneDrive へのユーザーのルート フォルダー オブジェクトのクエリを示します。ルート フォルダー オブジェクトは "me/skydrive" パスを使用して取得できます。

public async Task<object> GetRootFolder()
{
  LiveConnectClient client = new LiveConnectClient(_session);
  LiveOperationResult liveOpResult = 
    await client.GetAsync("me/skydrive");
  dynamic dynResult = liveOpResult.Result;
  return dynResult;
}

上記のコードでは、実行時に動的キーワードを使用して、基になる JSON 形式の文字列のクラス インスタンスを作成しています。これは手軽で使いやすい方法ですが、より形式的なクラス構造を必要とするいくつかの制限が生じる場合があることに注意してください。

GetAsync メソッドから返される結果には、要求したオブジェクトのすべてのプロパティが含まれます。図 4 に、ユーザーのルート フォルダーに返される JSON 形式の文字列の例を示します。

図 4 フォルダー オブジェクト クエリから返される JSON

{
  "id": "folder.abced3a35e6d1b",
  "from": {
    "name": null,
    "id": null
  },
  "name": "SkyDrive",
  "description": "",
  "parent_id": null,
  "size": 2957188732,
  "upload_location": 
    "https://apis.live.net/v5.0/folder.abced3a35e6d1b/files/",
  "comments_count": 0,
  "comments_enabled": false,
  "is_embeddable": false,
  "count": 25,
  "link": "https://onedrive.live.com?cid=abced3a35e6d1b",
  "type": "folder",
  "shared_with": {
    "access": "Just me"
  },
  "created_time": null,
  "updated_time": "2014-06-13T18:00:54+0000",
  "client_updated_time": "2012-10-22T19:50:04+0000"
}

OneDrive 内でクエリするときは、より具体的なクエリを作成すると便利です。たとえば、次のコードではルート ディレクトリにあるすべての子オブジェクトが返されます。

LiveOperationResult liveOpResult = await client.GetAsync("me/skydrive/files");

これには、フォルダーやファイルが含まれています。また、大量のデータが含まれる場合があります。

このディレクトリ内の写真の一覧だけを表示するにはどうすればよいでしょう。filter クエリ パラメーターを使用すればこれを実現できます。OneDrive API は、filter の他にも、limit、offset、search などのさまざまなクエリ パラメーターをサポートします。パラメーターは、必要なデータだけを取得するのに役立ちます。パラメーターを使用することで、ダウンロードするデータ量だけでなく、返されるデータの処理に必要なコードの量が少なくなります。

たとえば、次のクエリはルート ディレクトリ内の写真のリストのみを返します。フォルダーから写真だけを切り分けるコードを記述する必要はありません。

LiveOperationResult liveOpResult =
  await client.GetAsync("me/skydrive/files?filter=photos");

クエリ パラメーターの一覧とその使用方法については、 msdn.microsoft.com/library/dn631842 (英語) を参照してください。

フォルダーを操作する

どのようにファイル システムを操作する場合でも、論理的な開始場所はフォルダー構造になります。フォルダーをクエリする場合、me/skydrive のようなわかりやすいパス、または folder.abcde86dfb3a35e6d1b.ABCDED3A35E6D1B!532 のようなフォルダー ID の 2 種類の識別子のいずれかを使用します。フォルダーの子オブジェクトの一覧をクエリする場合は、パスに "/files" を追加します。たとえば、次のコードは、指定したフォルダー ID のすべてのファイル、フォルダー、およびアルバムの一覧を返します。

LiveOperationResult liveOpResult =
  await client.GetAsync("folder.abcde86dfb3a35e6d1b.ABCDED3A35E6D1B!532/files");

OneDrive は、folder と album という 2 種類のフォルダー オブジェクトを含みます。album は、ユーザーのルート OneDrive ディレクトリにあるフォルダーの特別な型と考えることができます。album には、写真とビデオのほか、フォルダー構造と追加のファイルを含めることができます。

次のクエリではルート ディレクトリ内のフォルダーのみが返され、アルバムはすべて無視されるため、フォルダーとアルバムの違いを把握することが重要になります。2 つの違いから予期せぬ結果になる場合があります。

LiveOperationResult liveOpResult =
  await client.GetAsync("me/skydrive/files?filter=folders");

フォルダーとアルバムの両方を返すには、filter の値に "folders,albums" を使用します。

先ほどのクエリでは、各フォルダーの子フォルダーを取得して、ユーザーの OneDrive アカウントのフォルダー構造全体を見ることができます。今回の関連ダウンロードには、2 つのページを含む MyPhotoAlbum という名前の XAML Windows ストア サンプル アプリを含めています。最初のページ FolderPage では、ディレクトリ構造を参照して、結果を GridView に表示します。Live SDK 呼び出しはすべて、OneDriveDataProvider クラスにラップしています。

図 5 に、フォルダー構造をスキャンするメソッドを示します。スキャンは、現在のフォルダー ID を渡し、filter 値として "folders,albums" を使用して行います。フォルダー ID がない場合、メソッドでは既定でルート ディレクトリが使用されます。

図 5 GetFolderItems メソッド

public async Task<List<object>> 
  GetFolderItems(string path, string filter)
{
  if (_session == null)
  {
    await InitProvider();
  }
  if (String.IsNullOrEmpty(path))
  {
    path = "me/skydrive";
  }
  if (!String.IsNullOrEmpty(filter))
  {
    filter = "?filter=" + filter;
  }
  LiveConnectClient client = new LiveConnectClient(_session);
  LiveOperationResult liveOpResult =
    await client.GetAsync(path + "/files" + filter);
  dynamic dynResult = liveOpResult.Result;
  return new List<object>(dynResult.data);
}

図 6 は、FolderPage に返された結果の例です。子フォルダーを選択すると、その子フォルダーをパラメーターに使用して、同じ FolderPage に移動します。これにより、戻る機能をナビゲーション スタックで維持して、上のフォルダー構造に戻ることができます。

FolderPage
図 6 FolderPage

wl.skydrive_update スコープを使用して更新アクセス権を要求した場合、API を使用してフォルダーの作成と削除も可能です。フォルダーに含まれるプロパティのうち、作成または変更できるのは name、description、および sort_by の 3 つだけです。フォルダーを作成する際は、親ディレクトリをパスまたは ID で指定し、JSON 配列に少なくとも name を指定する必要があります。新しいフォルダーの作成に必要な JSON の例を次に示します。

{
 "name": "My Favorite Photos",
 "description": "A folder full of my favorite photos."
}

SDK では LiveConnectClient の PostAsync メソッドを使用してこれを処理します。図 7 に、新しいフォルダーの作成に使用するメソッドを示します。

図 7 CreateFolder メソッド

public async Task<bool> CreateFolder(string path, string name)
{
  try
  {
    var folderData = new Dictionary<string, object>();
    folderData.Add("name", name);
    LiveConnectClient liveClient = new LiveConnectClient(_session);
    LiveOperationResult operationResult =
      await liveClient.PostAsync(path, folderData);
    dynamic result = operationResult.Result;
    return true;
  }
  catch (LiveConnectException exception)
  {
    return false;
  }
}

フォルダーの削除には DeleteAsync メソッドを使用します。このメソッドでファイルの削除も可能です。OneDrive の信頼性を維持することを忘れないこと、およびどのような削除関数も慎重に使用することが重要です。

LiveOperationResult operationResult = await liveClient.DeleteAsync(path);

ファイルを操作する

GetAsync メソッドでは、ファイルのプロパティが返されますが、ファイルそのものは返されません。OneDrive からファイルを取得する唯一の方法は、ダウンロードです。Windows ストア アプリ向けの Live SDK では、ダウンロード バックグラウンド タスクを作成してこれを処理します。このタスクでは、デバイスを完全に停止させることなく、ダウンロードを非同期に処理します。次のコードを使用して、OneDrive からファイルをダウンロードできます。

try
{
  LiveConnectClient liveClient = new LiveConnectClient(_session);
  LiveDownloadOperation op =
    await liveClient.CreateBackgroundDownloadAsync(filePath);
  var result = await op.StartAsync();
  // Handle result
}
catch
{
  // Handle errors
}

バックグラウンド ダウンロード操作から戻った後、LiveDownload­Operation インスタンスの StartAsync メソッドの呼び出しによってダウンロードが始まります。

ファイルのダウンロードと同様、OneDrive でファイルの追加または更新を行う唯一の方法はアップロードです。ファイルをアップロードするには、アプリで wl.skydrive_update スコープを使用して、書き込みアクセス権を要求している必要があります。CreateBackgroundUploadAsync メソッドは、フォルダー パス、ファイル名、ファイル含むストリーム、および上書きオプションを受け取ります。ファイルが既に存在する場合は、上書きオプションによって元のファイルに上書きすることも、元のファイルを保持して、アップロードする新しいファイルの名前を変更することもできます。フォルダーの更新関数と同様、この機能を使用する際には誤ってファイルを破損しないように注意してください。次に、ファイルのアップロード方法の例を示します。

try
{
  LiveConnectClient liveClient = new LiveConnectClient(_session);
  LiveUploadOperation op = await liveClient.CreateBackgroundUploadAsync(
    path, filename, fileStream, OverwriteOption.Rename);
  var result = await op.StartAsync();
  // Handle result
}
catch
{
  // Handle errors
}

ファイルをアップロードする前に、新しいファイルを格納できるだけの空き領域をユーザーが持っているのを確認することが重要です。利用可能な空き領域の容量を確認するには、GetObjectAsync メソッドでパス "me/skydrive/quota" を使用します。このメソッドは、quota と available の 2 つのプロパティを返します。返された値を使用して、ユーザーのアカウントの残りのバイト数を計算できます。

この API には、ファイルの処理に便利な機能があと 2 つあります。ファイルのコピーを作成する場合には、ファイルをダウンロードして、別の名前でアップロードします。しかし、これはごく単純な処理であるわりに、多くの帯域幅が使用されることがあります。また、フォルダー全体をコピーする、子フォルダーを別の親フォルダーに移動するなどの場合には、アップロードとダウンロードをしてコピーと移動を行うコードと帯域幅によって、処理が非常に面倒になります。この機能に対処するために、OneDrive API には MoveAsync という移動コマンドと CopyAsync というコピー コマンドがあります。どちらのコマンドも、移動するオブジェクト (ファイルまたはフォルダー) と移動先のパスの 2 つのパラメーターを受け取ります。図 8 にファイルのコピーに使用するメソッドを示します。

図 8 ファイルをコピーする

public async Task<bool> CopyObject(string path, string destination)
{
  if (_session == null)
  {
    await InitProvider();
  }
  try
  {
    LiveConnectClient liveClient = new LiveConnectClient(_session);
    LiveOperationResult operationResult =
      await liveClient.CopyAsync(path, destination);
    return true;
  }
  catch (LiveConnectException exception)
  {
    return false;
  }
}

まとめ

1 回のコラムで取り上げることができる API の数は限られています。Live SDK には他にも、写真やビデオの処理に関して特に多くの機能があります。ソリューションへの OneDrive の統合を検討している場合には、これらの他の機能も調べると非常に役立ちます。マイクロソフトは、OneDrive デベロッパー センター (dev.onedrive.com) を作成して、OneDrive API に関するすべての情報を 1 か所にまとめて提供しています。

ユーザーのファイルへのアクセスが必要な Windows ストア アプリ、Windows Phone ストア アプリ、またはその他のプラットフォーム向けアプリのいずれを作成している場合でも、OneDrive を追加して最も大切なファイルにユーザーがアクセスできるようにすることは、ユーザーの日常生活にアプリを組み込むために打って付けの方法です。優れたユーザー エクスペリエンスを構築するときには是非、OneDrive をサポートするようにしてください。


Tony Champion は、Champion DS の代表取締役であり、Microsoft MVP を取得しており、講演、ブログ、および著書で積極的にコミュニティに貢献しています。彼のブログは、tonychampion.net (英語) から、電子メールは tony@tonychampion.net (英語のみ) から利用できます。

この記事のレビューに協力してくれた技術スタッフの Mimi Sasouvanh に心より感謝いたします。
Mimi Sasouvanh は、マイクロソフトの Operation Systems Group Content チームのコンテンツ開発者で、OneDrive 開発、Azure インテリジェント システム サービスなどについて執筆しています。余暇は、家族とガーデニングやスケッチをして過ごしています。