「共有」契約-Windows 8メトロアプリケーションでのデータ転送

Windows 8では、メトロアプリケーションで、アプリケーション間でデータを転送(共有)する機能が登場しました。 将来、簡単にするために、この記事では「 共有 」という用語を使用します。

セキュリティ上の理由から、ユーザーはデータ転送を制御し、対応する共有チャームを使用してサイドパネルから呼び出されます

画像

またはキーボードショートカットのWin + H



例として、地図やお気に入りの写真からメールアプリケーションやツイッターに位置情報を転送する機能があります。



共有契約の実装は、非常に強力なマーケティングツールになる可能性があります。 ゲームやアプリケーションでの成果を友人と共有する機会を提供することで、アプリケーションの人気を高めることができます。



ここでは、データを「共有」するアプリケーションのプロバイダーアプリケーションという用語を使用します。 そして共有データを受信できるアプリケーションの受信側アプリケーション。



この記事は非常に膨大であることが判明しました。記事の概要は次のとおりです。



共有。 データプロバイダー

共有。 データ受信者。

標準形式の送受信。

テキストデータ形式の送受信。

リンクの送受信

グラフィックの送受信

ファイルの送受信

非標準データ型の送受信

文字列でのシリアル化を使用したオブジェクトの送受信

標準「非標準タイプ」。 Schema.orgベースのスキーマデータ

バイナリデータの送受信

遅延データ送信(データプロバイダー転送)。

大量のデータ(音楽、ビデオ)の転送の適切な編成

共有パネルへのリンクの追加(クイックリンク)

論理エラーを処理します。

データ共有の改善。 統計収集

共有に関する一般的な推奨事項。 実装のエラーを回避します。

プロバイダーアプリケーションの推奨事項。

プロバイダーアプリケーションの推奨事項。





共有契約の詳細な研究については、MSDNで2つの優れた実装例をダウンロードすることをお勧めします。

コンテンツソースアプリの共有サンプル

コンテンツターゲットアプリのサンプルの共有



共有。 データプロバイダー。



データを配信するアプリケーションの実装は非常に簡単です。 テキストを「共有」したいとします。



OnNavigatedToメソッドのページで、データ共有の要求ハンドラーを追加します。 OnNavigatingFromメソッドの共有イベントからサブスクライブを解除します



protected override void OnNavigatedTo(NavigationEventArgs e) { DataTransferManager.GetForCurrentView().DataRequested += Share_DataRequested; } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { DataTransferManager.GetForCurrentView().DataRequested -= Share_DataRequested; }
      
      







ハンドラーで、「共有」するデータを指定できます。 ある種のテキストを公開したいとします。



  void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Simple notepad"; args.Request.Data.Properties.Description = "Publication of the text"; args.Request.Data.SetText("Hello! World!"); }
      
      







Titleプロパティは必須です。指定しないと、データを「共有」しようとするとエラーが発生します。 同時に、Descriptionプロパティはオプションです。



ここで、データ共有を呼び出すと、データを受け入れることができるアプリケーションを選択するための提案を含む右側のパネルが表示されます。



画像



メールアプリケーションを選択すると、手紙のテキストがすでに記入されているフォームを受け取り、送信者を選択することで手紙を送信できます。 最初の2つのポイントは、メールアプリケーションの以前のアクティベーションから残っています。



共有。 受信機



データプロバイダーの「レシーバー」のレシーバーアプリケーションの実装も非常に簡単です。 ここでは、スタジオで既製のテンプレートを使用できます。



画像



このテンプレートを選択するとき、マニフェストにエントリを追加し、App.xamlのメソッドをオーバーライドして、新しいページを追加します。



このテンプレートの使用は考慮せず、「手動で」必要な要素を段階的に追加します。



まず、マニフェストファイルPackage.appxmanifestで、アプリケーションによる共有コントラクトのサポートを追加し、アプリケーションがサポートできるデータのタイプを示す必要があります。



画像



ここでは、Uri、Bitmap、HTML、StorageItems、RTFのサポートも追加できることがわかります。



これらのデータ型とカスタム形式のサポートについては、後ほど説明します。



次に、App.xamlでOnShareTargetActivationを再定義する必要があります。このメソッドでは、テキストを抽出できる場所からリンクを転送できます。



  protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args) { var frame = new Frame(); frame.Navigate(typeof(TargetPage), args.ShareOperation); Window.Current.Content = frame; Window.Current.Activate(); }
      
      







これで、TargetPageページで、転送されたテキストを抽出できます。 簡単にするために、ページにTextBlockを追加し、そのテキストプロパティを設定します。



これを行うには、ページコードでOnNavigateToメソッドを再定義し、テキストを抽出します



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation)e.Parameter; txtBlock.Text=await shareOperation.Data.GetTextAsync(); } }
      
      







以上です。 レシーバーアプリケーションをインストールし、その後センダーアプリケーションを起動し、共有時にレシーバーアプリケーションを選択すると、次のウィンドウが表示されます。



画像



私たちのアプリケーションは、別のアプリケーションから渡された文字列を受け取りました。



注目すべきこと。 アプリケーションは、タイトルとともにサイドポップアップに表示されます。 リンク先ページのデザインを計画するときは、この状況を考慮する必要があります。 (おそらく、リリースの値は異なりますが、いくつかの異なるモニターでは、パネル幅は常に645ピクセルでした)。



また、タイトルに影響を与えることはできません。タイトル(バック矢印、アプリケーションの名前、アプリケーションのロゴ)でレシーバーページがアクティブになります。 この点で、このページのナビゲーションを作成する必要はありません。 理想的には、これはナビゲーションのない単一のページである必要があります。



標準形式の送受信。



かなり頻繁に、文字列よりもやや複雑なデータ形式を送受信する必要があります。 最も一般的に要求される形式については、対応するAPIサポートが追加されました。 Text、Rtf、Html、Uri、Bitmap、StorageItems(ファイル)を標準形式として転送できます。 それぞれを同時に送信できます。 つまり Text、Html、Bitmapなどを同時に送信および抽出できます



テキストデータ形式の送受信



Text、Rtf、Htmlの最初の3つの形式は、同じ方法で送受信されます。



トランスミッション:



  args.Request.Data.SetText("..."); args.Request.Data.SetRtf("..."); args.Request.Data.SetHtmlFormat("...");
      
      







レセプション:



まず、テキスト、HTML、Uri形式の「受信」をサポートするために、対応するエントリをマニフェストに追加します。



対応するデータ取得コード:



  shareOperation.Data.GetTextAsync(); shareOperation.Data.GetRtfAsync(); shareOperation.Data.GetHtmlFormatAsync();
      
      







一度に複数の形式をサポートする場合、特定のデータ型を1つだけ受け取る可能性が高く、パッケージ内のデータの「コンテンツ」を確認する必要があります。



  if(shareOperation.Data.Contains(StandardDataFormats.Text)) { var text = shareOperation.Data.GetTextAsync(); } if(shareOperation.Data.Contains(StandardDataFormats.Html)) { var html = shareOperation.Data.GetHtmlFormatAsync(); } if(shareOperation.Data.Contains(StandardDataFormats.Rtf)) { var rtf = shareOperation.Data.GetRtfAsync(); }
      
      







リンクの送受信



Uriの送信と受信はほぼ同じです。



 args.Request.Data.SetUri(new Uri("http://akhmed.ru/post/2012/07/19/share_contract_win8.aspx"));
      
      







レセプション:



 shareOperation.Data.GetUriAsync();
      
      







グラフィックの送受信



もう少し面白いのは、画像の送受信です。



別のサーバーから画像として転送できます



 args.Request.Data.SetBitmap(RandomAccessStreamReference.CreateFromUri(new Uri("http://freshyourmood.com/wp-content/uploads/2012/04/pure-water-aquatecuk.wordpress.com_.jpg")));
      
      







プロジェクトからとてもローカル



 args.Request.Data.SetBitmap(RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///apple.jpg")));
      
      







画像の抽出も非常に簡単な操作です。 最初に、宛先アプリケーションのマニフェストに適切なエントリを追加します:ビットマップ。



次に、たとえば、ページ上のテキストと画像を対応するxamlコードで表示します。



  <StackPanel Orientation="Horizontal" VerticalAlignment="Top"> <Image x:Name="img" Width="200" Height="200"></Image> <TextBlock x:Name="txtBlock" Margin="24" Text="start page text" Style="{StaticResource HeaderTextStyle}" /> </StackPanel>
      
      







「抽出」データのコード:



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation) e.Parameter; if (shareOperation.Data.Contains(StandardDataFormats.Text)) { txtBlock.Text = await shareOperation.Data.GetTextAsync(); } if (shareOperation.Data.Contains(StandardDataFormats.Bitmap)) { var bitmapReference = await shareOperation.Data.GetBitmapAsync(); var bitmapImage = new BitmapImage(); bitmapImage.SetSource(await bitmapReference.OpenReadAsync()); img.Source = bitmapImage; } } }
      
      







そして、結果を賞賛することができます。



画像



同じ原理により、アイコン画像を転送できます。 構文は少し異なります。



トランスミッション:



  args.Request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///apple.jpg"));
      
      







レセプション:



  var bitmapReference = shareOperation.Data.Properties.Thumbnail;
      
      







したがって、2つの画像を一度に転送できますが、パフォーマンス上の理由から、2番目のアプローチを使用する価値があるのは、画像がローカルにあり、サイズが大きくない場合のみです。



ファイルの送受信



契約を通じて、システムで利用可能なファイルを転送できます。 WinRTのデフォルトでは、ファイルシステムに直接アクセスできず、受信したファイルを、たとえばFilePickerコントラクトを介して転送できます。 一般に、ファイルの操作は別の記事に値しますが、FilePickerコントラクトの使用は非常に簡単です。



たとえば、アプリケーションでの作業中に、いくつかのファイルをアプリケーションにアップロードできます。



簡単にするために、クリックしてファイルを選択するボタンを追加します。



 <Button Content="LoadFiles" Click="LoadFiles_Click" HorizontalAlignment="Left" Margin="268,82,0,0" VerticalAlignment="Top" Width="139"/>
      
      







そして、ユーザーが選択したファイルへのリンクを保存します。



  private IReadOnlyList<StorageFile> files; private async void LoadFiles_Click(object sender, RoutedEventArgs e) { var filePicker = new FileOpenPicker { FileTypeFilter = {"*"} }; files = await filePicker.PickMultipleFilesAsync(); }
      
      







次に、これらのファイルを転送する共有イベントを示します。



  void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "file sharing"; if(files!=null) { args.Request.Data.SetStorageItems(files); } }
      
      







ファイルの「レシーバー」の実装も非常に簡単です。 マニフェストで、StorageItemsファイルのサポートを追加するか、[ファイルタイプをサポートする]チェックボックスをオンにする必要があります。



次に、例として、リストボックスにファイルをリストします。



  <ListBox x:Name="listBox"></ListBox>
      
      







そして、受信したファイルの名前をこのリストにバインドします



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation)e.Parameter; var files=await shareOperation.Data.GetStorageItemsAsync(); listBox.ItemsSource = files.Select(i=>i.Name); } }
      
      







その結果、おおよそ次の結果が表示されます。



画像



非標準データ型の送受信。



標準形式の存在により、ほとんどのシナリオでの作業が大幅に簡素化されます。 それでも、私たちにふさわしい形式がない場合、スクリプトが必要になることがよくあります。 製品のリストを処理するアプリケーションがあるとします。 多くのフィールドがあり、そのうちのいくつかはオプションです(名前、価格、カテゴリ、ブランド、ユニットなど)。 ここで、この形式の製品でも機能する別のアプリケーションがあり、別のアプリケーション用のフォームにデータを配置する機能を追加したい場合。



文字列のシリアル化でオブジェクトを送受信します。



データを何らかの形式(CSV、XML、JSON)にシリアル化し、解析して取得できます。 ただし、標準形式は機能しません。 まず、これにテキストまたは別の形式を使用すると、標準形式をサポートするすべてのアプリケーションが開き、メールアプリケーションを選択すると、ユーザーには理解できないテキストで満たされた文字が表示されます。 さらに、詳細のない製品のリストを持つ別のユーザーにデータを送信できるように、テキストまたはHTML形式を引き続き使用できるようにしたいと考えています。



この場合、特別なデータ形式が役立ちます。



まず、製品などの形式の名前を考え出す必要があります。 (おそらく、私たちの前か後に誰かが同じ名前のフォーマットを使用し、それらのフォーマット製品に名前を付けるという素晴らしいアイデアを思いつくでしょう。簡単にするため、Productのままにします)。



レシーバーとサポーターの両方に次のProductクラスがあるとします:



  public class Product { public string Name { get; set; } public int Count { get; set; } }
      
      







シリアライザー:



  public class JsonSerializer { public static string Serialize<T>(T item) { var dataSerializer = new DataContractJsonSerializer(typeof(T)); var ms = new MemoryStream(); dataSerializer.WriteObject(ms,item); ms.Position = 0; return new StreamReader(ms).ReadToEnd(); } public static T Deserialize<T>(string value) { var dataSerializer = new DataContractJsonSerializer(typeof(T)); return (T)dataSerializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(value))); } }
      
      







サプライヤアプリケーションでは、製品をシリアル化し、形式識別子を指定して送信できます。



  void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Product sharing"; var product = new Product() { Name = "Bread", Count = 2 }; var productJson = JsonSerializer.Serialize(product); args.Request.Data.SetData("product",productJson); }
      
      







「受信者」の実装:



受信者アプリケーションでは、マニフェストで製品フォーマットをサポートするように指定する必要があり、次のコードを使用して製品を取得できます。



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation)e.Parameter; if(shareOperation.Data.Contains("product")) { var productJson = await shareOperation.Data.GetTextAsync("product"); var product = JsonSerializer.Deserialize<Product>(productJson); txtBlock.Text = product.Name + " " + product.Count; } } }
      
      







アプリケーションを起動すると、データが正常に転送されたことを確認できます。



画像



この場合、通常の文字列を特別な形式で受け渡しました。 GetTextAsync()の形式を指定せずに文字列を取得できます。



標準「非標準タイプ」。 Schema.orgベースのスキーマデータ



独自のデータ形式ではなく、一般的な形式を使用したい場合があります。



たとえば、製品で動作する他のアプリケーションがある場合、これらのアプリケーションでデータの受信と送信を整理することは理にかなっています。



そのような場合、 schema.orgリソースでスキーマを使用することが公式に推奨されています。



まず、エンティティのタイプ(書籍、音楽、映画、製品)を判別する必要があります



適切なエンティティを選択すると、スキーマデータに従ってJSONの文字列を送信または受信する必要があります。



エンティティ「製品」(http://schema.org/Product)を選択するとします。



プロバイダーアプリケーションの実装:



データ転送は、上記のネイティブ形式の送信に完全に類似しています。違いはJSON形式のみです。



  async void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Product sharing"; var productFormat = @"{ ""type"" : ""http://schema.org/Product"", ""properties"" : { ""name"" : ""{0}"", ""description"" : ""{1}"", ""productID"" : ""{2}"" } }"; var productJson = String.Format(productFormat, "Olive oil", "description of product", "8410660101481"); args.Request.Data.SetData("http://schema.org/Product",productJson); }
      
      







受信機アプリケーションの実装



このスキーマをサポートするには、マニフェストでschema.org/Productデータ形式を指定する必要があります



画像



データの読み取りは、上で調べた行の読み取りと同様に実行されます。



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { shareOperation = (ShareOperation)e.Parameter; var productJson = await shareOperation.Data.GetTextAsync("http://schema.org/Product"); JsonObject productObject = JsonObject.Parse(productJson); JsonObject properties = productObject["properties"].GetObject(); var productId = properties["productID"]; var productName = properties["name"]; var productDescriptions = properties["description"]; } }
      
      







バイナリデータの送受信



場合によっては、文字列ではなくバイナリデータを渡す方が簡単です。 (たとえば、djvuエディターがあり、生の形式でデータを転送したい場合)。



ファイルを開き、開いているファイルからストリームへのリンクを転送し、受信者アプリケーションでこのストリームを読み取ることができます。



メモリ内のストリームからデータを転送するより興味深い例を考えてみましょう。



  async void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Product sharing"; var product = new Product() { Name = "Bread", Count = 2 }; var stream = new InMemoryRandomAccessStream(); using(var writer=new DataWriter(stream)) { writer.WriteInt32(product.Name.Length); writer.WriteString(product.Name); writer.WriteInt32(product.Count); await writer.StoreAsync(); await writer.FlushAsync(); writer.DetachStream(); } stream.Seek(0); args.Request.Data.SetData("product", stream); }
      
      







受信側アプリケーションでは、このストリームを読み取って解析できます。



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation)e.Parameter; if (shareOperation.Data.Contains("product")) { var stream = await shareOperation.Data.GetDataAsync("product") as IRandomAccessStream; var product = new Product(); using(var streamReader=new DataReader(stream)) { await streamReader.LoadAsync((uint) stream.Size); var len = streamReader.ReadInt32(); product.Name = streamReader.ReadString((uint) len); product.Count = streamReader.ReadInt32(); } txtBlock.Text = product.Name + " " + product.Count; } } }
      
      







遅延データ送信(データプロバイダー転送)



前の例には重大な欠点があります。 ユーザーがアプリケーションを使用せずに共有操作をキャンセルした場合でも、常にデータを初期化および準備します。 別の方法として、データを共有することはできませんが、データプロバイダーと受信側アプリケーションは、ユーザーがアクティブにした後にデータを読み取ることができます。 データプロバイダーを使用して、データプロバイダーで最後の例を作り直しましょう。



  async void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Product sharing"; args.Request.Data.SetDataProvider("product",BinaryDataHandler); } private async void BinaryDataHandler(DataProviderRequest request) { try { var product = new Product() { Name = "Bread", Count = 2 }; var stream = new InMemoryRandomAccessStream(); using (var writer = new DataWriter(stream)) { writer.WriteInt32(product.Name.Length); writer.WriteString(product.Name); writer.WriteInt32(product.Count); await writer.StoreAsync(); await writer.FlushAsync(); writer.DetachStream(); } stream.Seek(0); request.SetData(stream); } finally { request.GetDeferral().Complete(); } }
      
      







このアプローチの主な利点は、共有ウィンドウの表示が速くなり、特定のアプリケーションが選択された後にのみBinaryDataHandlerメソッドが呼び出されることです。 また、ユーザーが共有操作をキャンセルすると、メソッドはまったく呼び出されません。



大量のデータ(音楽、ビデオ)の転送の適切な編成



アプリケーションが大量のデータを配信する場合、すべてのデータが転送されるまでユーザーを待たせないでください。



データの受信が既に完了しており、インターフェースで必要なアクションをすべて実行した場合(たとえば、メールインターフェースの[送信]ボタンまたはユーザーからの確認が明らかに必要な[保存]ボタンをクリックした場合)、メソッドを呼び出すことができます:



 shareOperation.ReportCompleted();
      
      







これは、すべてのデータ転送操作が完了したことをシステムに通知し、受信側アプリケーションの共有インターフェースを閉じます。



転送されるデータの量が多すぎる場合、ユーザーに強制的に待機させるべきではありません。



メソッドを呼び出すことができます



 shareOperation.ReportStarted();
      
      







大きなデータパケットを抽出する前に、転送プロセスを開始しますが、同時に共有インターフェイスを非表示にし、ユーザーに作業を継続する機会を提供します。



次に、メソッドを呼び出す必要があります



  shareOperation.ReportDataRetreived();
      
      







これにより、必要なすべてのデータが既に抽出され、元のアプリケーションを解放できることをシステムに通知します(ユーザーが以前に閉じた場合)。



転送が完了すると、メソッドを呼び出すことができます



 shareOperation.ReportCompleted();
      
      







または方法



 shareOperation.ReportError("error description");
      
      







データ転送の成功またはエラーをシステムに通知します。



後者の場合、ユーザーはエラーに関する通知を受け取り、共有を再度開き、以下のリンクに従って転送ステータスを確認するとエラーを確認できます。



データ転送アプリケーションがBackgroundTransferTaskを使用する場合、適切なメソッドを呼び出すことにより、データ転送のこのメソッドを使用することをシステムに通知できます。



  shareOperation.ReportSubmittedBackgroundTask();
      
      







共有パネルにリンクを追加します。



データ転送後の受信側アプリケーションでは、追加の操作を行う必要があるとしましょう。 たとえば、メールアプリケーションにテキストを送信する場合、ユーザーはメッセージの送信先の宛先も選択する必要があります。 この場合、メールアプリケーションは最後のアクションへのクイックリンクを作成します。 次回、「to」フィールドでこのクイックリンクを選択すると、対応するエントリが入力されます。



受信アプリケーションに製品のリストが1つもないとします。 製品リストのリストがあります。 ユーザーがアプリケーションを選択し、製品を転送するリストを選択した場合、このリストへのクイックリンクを提供できます。



レシーバーアプリケーションにクイックリンクを追加する方法を見てみましょう。



  private async void ButtonSaveLink_Click(object sender, RoutedEventArgs e) { var quickLinkInfo = new QuickLink { Id = "homeListId", Title = "Add to Home list", SupportedFileTypes = { "*" }, SupportedDataFormats = { //   StandardDataFormats.Bitmap, "product" } }; try { var iconFile = await Package.Current.InstalledLocation.CreateFileAsync("assets\\Logo.png", CreationCollisionOption.OpenIfExists); quickLinkInfo.Thumbnail = RandomAccessStreamReference.CreateFromFile(iconFile); shareOperation.ReportCompleted(quickLinkInfo); } catch (Exception) { shareOperation.ReportCompleted(); throw; } }
      
      







XAMLの対応するコード



 <Button Content="Save" Click="ButtonSaveLink_Click" />
      
      







これで、レシーバーアプリケーションで[保存]ボタンを押すと、次回共有するときにクイックリンクが表示されます。



画像



次回は、ユーザーがクリックしたクイックリンクを特定することで、同じタイプのアクションを簡素化できます。



  shareOperation = (ShareOperation)e.Parameter; if(shareOperation.QuickLinkId=="homeListId") { //handle selected list }
      
      







このリンクを自動的に追加してみませんか? ユーザーがアプリケーションをアクティブにした後、アクションを実行できない場合があるためです。



共有APIは、リンクを追加すると宛先アプリケーションが最小限になるように特別に設計されています。 したがって、リンクを追加することは、実行可能な最後の操作でなければなりません。 つまり 受信側アプリケーションを選択してリストを選択すると、すぐに保存してクイックリンクを追加します。 または、リストを選択することにより、選択を変更し、[保存]ボタンをクリックした後にのみ選択したリストに保存する機会を与えます。



リンクの関連性がなくなった場合、アプリケーションからクイックリンクを削除できます。 (たとえば、この識別子を持つリストはもうありません)。



  shareOperation.RemoveThisQuickLink();
      
      







論理エラーを処理します。



ソースアプリケーションページがデータ共有をサポートしていない場合、共有しようとすると、ユーザーには「このアプリは共有できません」というメッセージが表示されます。



特定の製品の詳細にアクセスして共有する必要があることをユーザーに伝えたい場合があります。または、このページでいくつかの製品を共有用にマークする必要があります(代替手段として、あまり多くない場合はすべてのデータを送信できます)。



いずれの場合でも、必要に応じて、配信用のデータを提供できない理由とユーザーが行う必要があることをユーザーに通知できます。



例:



  async void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Product sharing"; args.Request.FailWithDisplayText("please select products for sharing"); }
      
      







ページを「共有」しようとすると、次の結果が表示されます。



画像



データ共有の改善。統計の収集



それ自体でデータを共有することは、アプリケーション間の相互作用のためのほぼ普遍的なAPIです。開発者として、ユーザーが可能な限り快適になるようにあらゆることを行う機会があります。



どのアプリケーションが最も頻繁にデータを転送し、どのアプリケーションから最も頻繁にデータが送信されるかを知りたい場合があります。



前者の場合、受信側アプリケーションでサポートされる形式の数を改善できます。または、受信側アプリケーションでは、最も人気のあるプロバイダーからのデータに対するより良いサポートを追加できます。



データが最も頻繁に提供されるアプリケーションを見つけることは非常に簡単です。アプリケーション選択イベントにサブスクライブして、統計を収集できます



  protected override void OnNavigatedTo(NavigationEventArgs e) { DataTransferManager.GetForCurrentView().DataRequested += Share_DataRequested; DataTransferManager.GetForCurrentView().TargetApplicationChosen += ShareText_TargetApplicationChosen; } protected override void OnNavigatingFrom(NavigatingCancelEventArgs e) { DataTransferManager.GetForCurrentView().DataRequested -= Share_DataRequested; DataTransferManager.GetForCurrentView().TargetApplicationChosen -= ShareText_TargetApplicationChosen; } void ShareText_TargetApplicationChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args) { var targetAppName = args.ApplicationName; //  }
      
      







同様に、受信側アプリケーションでは、どのアプリケーションからデータが配信されるかを確認できます。



  protected async override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter != null) { var shareOperation = (ShareOperation)e.Parameter; //   var sourceAppName = shareOperation.Data.Properties.ApplicationName; //Url      (null    ) var sourceAppMarketUrl = shareOperation.Data.Properties.ApplicationListingUri; //  } }
      
      







共有に関する一般的な推奨事項。実装のエラーを回避します。



ここに提示されているすべての推奨事項が公式であるわけではなく、私が自分で書いた推奨事項の一部は批判的に解釈されるべきです。



プロバイダーアプリケーションの推奨事項。



コンストラクターで共有要求イベントをサブスクライブする必要はありません。別のページに移動すると、データ共有の登録を正しく解除できなくなります。これにより、ユーザーがこれらのページにアクセスした場合、マルチページアプリケーションでは、共有にサブスクライブしているすべてのページで共有が機能するという事実につながります。



最も正しい解決策は、ページに移動するときに共有でサインオンし、ページを離れるときに共有からサブスクライブ解除することです(OnNavigateTo、OnNavigateFromメソッド)。簡単にするために、これらのアクションを自動化するベースページを作成できます。



または、アプリケーションがアクティブ化されたときに共有をサブスクライブすることができます。この場合、現在アクティブなページとその状態に応じて、単一の共有マネージャーからデータを提供します(たとえば、各ページのサブスクライブと共有を回避するため)。



一度に複数の形式でデータを提供することをお勧めします。専用のTo Doリスト形式を使用している場合でも、ユーザーが現在のTo Doリストを友人などにメールで送信できるように、テキストまたはHTMLでデータを配信する機能を提供します。



アプリケーションが大量のデータを転送する場合は、できるだけ早く共有操作を開始するために、データプロバイダーの転送を使用することをお勧めします。



必要に応じて、現在のページに配信用の情報があることをユーザーに伝えることができます(たとえば、ゲームがあるか、アプリケーションにゲーム要素と実績がある場合、データ共有を介して友人と共有できるものをユーザーに伝えることができます)。共有パネルを開くヒントボタンを追加できます。



次のコードは共有パネルを開きます。ユーザーがアプリケーションのボタンをクリックした場合にのみ使用することをお勧めします。



 DataTransferManager.ShowShareUI();
      
      







受信側アプリケーションの推奨事項。



データは一度に複数の形式でアプリケーションに送られることに注意してください。使用可能な形式のリスト全体は、パラメーターから取得できます:shareOperation.Data.AvailableFormats



また、shareOpertaion.Data.Contains()メソッドを使用して、特定の形式の可用性を確認することもできます。



音楽、ビデオなどの大量のデータを転送する場合データプロバイダーとshareOperation.Reportの可能性を使用します...();転送を非同期的に実行し、ユーザーが操作の完了を待つことを強制しないため。



必要に応じて、共有パネルにリンクを追加して、同じタイプのアクションを簡素化してください。 scheme.orgの



標準を使用している場合 データの形式が間違っていると常に想定し、適切なチェックとエラー処理を実行します。



All Articles