2018年1月28日日曜日

App を Windows Timeline に対応させる 2/2

UWP App のTimeline 対応、実践編です。拙作のApp F10 image bbs browser で行った作業に即して説明してみます。

この記事は
App を Windows Timeline に対応させる 1/2
の続きです。

Windows Timeline 表示例


前準備


Fall Creators Update レベルのAPIを使うため、App のプロジェクト プロパティ→アプリケーションでMinVersionを 10.0.16299 にします。





必須では無いですが、このNuGetパッケージも追加します。後述するAdaptive Cards のJson 生成はこれが無いとやってられないです。

AdaptiveCards - NuGet Gallery

https://www.nuget.org/packages/AdaptiveCards/
※注意!!! (Added 7 March 2018)
NuGet には上のものとは別に、"Microsoft.AdaptiveCards" が存在します。こちらは既に更新が終了しており、もう使われていません。ただ困ったことにGoogleで"NuGet AdaptiveCards" で検索するとこちらが表示されてしまうようです。気を付けてくださいね。

Microsoft.AdaptiveCards (Deprecated)
https://www.nuget.org/packages/Microsoft.AdaptiveCards/


UserActivity を生成するClassには以下二つのusingを追加します。

using Windows.ApplicationModel.UserActivities;
using AdaptiveCards;


User Activity の作成とOS への登録


前の記事でも触れましたが、App 上の作業の節目…ドキュメントを開いた時など…のタイミングでUserActivity を生成し、OSに登録します。OS はTimeline 上にこのUserActivity をタイルとして表示します。


UserActivity の作成と登録



基本、これだけでUserActivityの登録が可能です。ただこの例では Adaptive Cards を使っていないため、Timeline 上の表示は以下のように大変シンプルなものになります。実際には殆どの場合、これから説明するAdaptive Cards を使ってタイルの中身を組み立てていくことになるでしょう。



Adaptive Cards を使わない表示例





Adaptive Cards


詳しい説明は省きますが、Microsoft が考える通知カードの標準形といったところです。カードの中身…データのJSONスキームと、コンテナ…カードを表示するデバイスの能力を記述するスキームが分離してあるのが特徴でしょうか。
Microsoft のAdaptive Cards 紹介ページを見て頂くと感じが判るかと思います。

Weather Compact - AdaptiveCards Sample



画面の右ペインにコンボボックスがあり、ここから表示するコンテナを選択できます。共通のJSONデータに対して、各デバイス…Windows の通知トースト、タイル、Teams, FacebookにKik、そしておそらくは他プラットフォーム…で「大体」意味が伝わるように表示しますよ、という。

その各デバイスの中にWindows Timeline も並んでいます。触っていると、表現力は他のデバイスと比べてそれほど高くはないようです。また、入力系のようにそもそもTimeline の使用方法にそぐわないものもあります。

さて、F10 ではこのようなJSONを渡しています。以下のような背景画像付きのTileになります。

Adaptive Cards を使った例



このJSON文字列、素から文字列を足し合わせて気合で作っても良いのですが…上品に行うために 、「前準備」で触れた AdaptiveCards NuGet パッケージがあります。このパッケージ、別にUWP App用というわけでも無いので…Xamarin、その他 Desktop App等でも、.NET 環境でAdaptive Cards を作る場合は全部これでいけるはずです。

これで、この一つ上で貼ったJSON文字列が生成されます。


Protocol Activation によるAppの起動・アクティベーション対応


ここは特にTimeline ユニークな話でもないので省略しますが、このような作業になります。

  • Package.AppxManifest で自アプリのプロトコル名を登録する
  • Appx.Xaml.cs にOnActivate を追加し、args.Kind == ActivationKind.Protocol だったらばパラメータを拾ってページを作る・または渡す


URI のアクティブ化の処理


注意など


  • たまに、Timeline 上の表示が正しく行われない場合があります。特にこちらでAppのUserActivity 生成コードを弄った場合等に多いようです。この場合、一旦ログオフ→ログオンで元に戻る場合が多いです。
  • 良くあるのは、作成したAdaptive Cards JSON文字列が不正で登録に失敗する場合です。この場合 userActivity.SaveAsync() で黙って落ち、特に例外が発生しないため大変分かりにくいです。 はまりがち。
  • 上でも触れましたが、Timeline 上のAdaptive Card ではあまり凝った表現は出来ないようです。先にAdaptiveCards.io のテストサイトで表現が実現可能かどうか確認すると良いでしょう。
  • Windows Timeline 上の画面からインクリメンタルサーチが可能ですが、ここで検索対象となるのはuserActivity.VisualElements.DisplayText と、Applicationの名前です。Adaptive Cards の中身は使われないようです。逆にAdaptive Cards を使用する場合 DisplayText は表示されませんので、ここに検索で拾ってほしいキーワードを追加しておくと良いです。


2018年1月3日水曜日

App を Windows Timeline に対応させる 1/2

まとめ

  • Windows Timeline は対応が簡単な割に得られる物が大きい
  • ただ、アプリにより向き不向きがある

Windows Timeline、最近のWindows 10 Insider Preview で使えるようになりました。UWP App をこのWindows Timelineに対応させる開発者向けガイドも出ています。今回自分のApp を対応させる機会があり、作業量が少ない割には効果が大きかったので紹介しようという趣旨の記事です。

※この記事には続きがあります。
App を Windows Timeline に対応させる 2/2


Windows Timeline とは


Windows 10 の次期大規模更新(RS4?)に入ると言われている新機能です。2018年1月時点では Insider Preview Build 17063 で使うことが可能です。アプリではWebブラウザ Edge、フォト等が対応しています。宣伝になりますが、拙作の画像掲示板ブラウザ F10 も対応しています。

F10 Image bbs browser
https://www.microsoft.com/store/apps/9nblggh1ntrd

なお、API 自体はWindows 10 Fall Creators Update (FCU) から入っており、SDKもFCUレベルの16299から既に対応しています。このため、現時点でもWindows Timeline 対応アプリをビルドし、ストアに上げることが可能になっています。


Windows Timeline
タスクバー左から3番目のアイコン、またはWin+Tabで表示されます


※以降、仕組みについては推測込みです。ウソが混じっているかもしれません。またIP 17063 の動作を元に書いているため、今後変わるかもしれません。


対応に必要な作業と得られる効果


仕組み・方法を説明する前に、得られる効果を書きましょう。Timeline に対応するためにアプリ側でやる事は主に二つで、


  • 適切なタイミングでUserActivityをOSに投げる
  • Protocol Activation …Uriを使った起動・アクティベーションに対応する


前者はかなり楽に済みます。後者は…アプリに依るのですが、いわゆるブラウザ系、URLのように文字列一本でアプリの状態を記述できる場合は楽に対応できるのではと思います。ここは後でまた触れます。

これらを行うだけで、アプリの操作履歴の同期がデバイス間で、OS組み込みの洗練されたUIで可能になります。PC+ノート+タブレット…PC複数持ちが当たり前の昨今、簡単に作業状態をデバイス間で引き継げるのは使ってみると大変に便利です。

この操作履歴の同期、Timeline無しで自分でやるのは結構手間でして…

  • Roaming Folder を使ってデバイス間で同期する…Appの履歴DBから一部をRoamingFolderに書き出し、変更を検知してDBに取り込む等
  • Project Romeを使う…リモートデバイスを列挙し履歴データを送受信する仕掛けをRemote AppServiceで作る

等を行う事になります。どちらもある程度安定動作させるにはそこそこ工数がかかります。拙作のブラウザ F10ではこの両方を実装してあるのですが、それに比べると今回のUserActivity を使ったWindows Timeline への対応は圧倒的に簡単、そしてユーザビリティは優れています。お得過ぎる。


右上の検索ボックスからインクリメンタルサーチが出来ます。便利。
検索対象になるのはVisualElements.Title と Appの名前で、AdaptiveCardの中は見てくれないようです。
この例ではVisualElements.Titleにスレ名+板名+BBS名をまとめて登録していますが、表示しているのはAdaptiveCard になっています。


同じMicrosoft Account を使うデバイスにFall Creators Update のシステムが居る場合、
UserActivityはこのようにActionCenter上に表示されます。
クリックするとTimeline同様にAppが起動します。
FCUから登録したUserActivityは、他の17063 システムのTimeline上に表示されます。


他のデバイスで登録されたUserActivityは、右上にそのデバイス名が表示されます。



Windows Timeline の仕組み


アプリケーションはOSに対し、自分の状態を「UserActivity」という単位で投げます。
OSはそのアプリ毎の「UserActivity」を時系列に並べて表示します。それが「Windows Timeline」です。

ユーザーがWindows Timeline 上のタイルをクリックすると、OS はUserActivity内のプロパティ ActivateUri をパラメータにしてアプリを起動又はアクティベートします。

UserActivityを「どのタイミングで」OSに投げるかはアプリ設計者に任されています。Webブラウザなら新しいタブを開いた、Officeならドキュメントを開いた、という操作の節目でUserActivityを発行するものが多いようです。

OSは、この投げられたUserActivity を一台のローカルマシンだけではなく同じMicrosoft Account でログインしている複数のシステムで共有します。この同期、Project Rome と呼ばれる Microsoft Graph ベースの仕組みを使っているようです。このため、Microsoft Graph に対してRESTで直接叩く事により、プラットフォーム非依存で使う事が可能…というように見えます(ただ、Timeline の「表示」自体は別にアプリが必要でしょう。Android ならば Microsoft Launcher あたりが適任っぽいですが。また、Rome系のAPIはGraph上だとBeta扱いのが多いので使っていいのか少し微妙)。


UserActivity 


UserActivity、色々プロパティはついているのですが、まずは一発表示してみたい時に必須なのは以下二つです。


  • UserActivity.ActivationUri … Appをアクティベートするときに使うUri
  • UserActivity.VisualElements.Title 名前 表示・検索に使われます(後述のAdaptiveCardを使う場合表示はそちらになる)


ActivationUri は一番大事なもので、ユーザーがTimeline 上のタイルをクリックするとOSはこれを使ってAppを起動します。

UWP Appでは、App 毎に独自のActivation Protocol をOSに登録することが出来ます。
例えばF10 が入っている環境ですと、Win+Rの名前をつけて実行、で

ddlgf10://a.4cdn.org/a/thread/166549698.json&view=post

とするとF10が起動し、そのスレが開きます。
これは、

  1. OSは ddlgf10:// をプロトコルとして認識し、(AppxManifestで指定する)
  2. パラメータをF10に渡し、
  3. F10 はOnActivate でそれを受け取り処理する(というコードを自分で書く)

という仕組みになっています。Windows Timeline はこのActivationUriを含むオブジェクトUserActivity を折々のタイミングでOSが記憶し、リストとして表示するという仕掛けになります。


Timeline への向き・不向き


上で説明したように、このTimeline の核は


  • アプリの状態…アプリが使うリソースも含めて…が、一行のUri で示される


事にあります。これが出来ないアプリの場合、あまり役に立てる事ができないです。

例を挙げると、

・F10 の場合… これはブラウザアプリです。Web上の画像掲示板のスレッドを取得し、XAMLでレンダリングします。
このため、アプリの状態は「表示するスレのURL」+「F10上の表示形式オプション」で完全に記述することが可能です。
そしてこれは、システムユニークでは無く…どのシステムでも共通に(ネットに繋がれば)使用可能です。リソースはネット上のスレだからです。

・画像ブラウザの場合
例えばピクチャライブラリ上の画像 hoge.jpg を表示する場合を考えます。これをURLとして持ち、UserActivityとして登録する事は可能でしょう。ただ、このリソースはローカル…このデバイス上でのみ参照可能であるため、他のデバイス上でUserActivity をWindows Timeline に表示する意味がありません。
こういう場合、Timeline 上に表示するActivity としては不適切かもしれません。
逆にリソースがクラウド上にある場合…例えば画像がOneDrive上にある場合はTimelineで扱うにはピッタリでしょう。
他にもブックリーダー等、OneDriveとTimelineとの食い合わせはかなり良いです。OneDrive上の本のUri+リーダーでの読書位置、を合わせた物をUriとしてUserActivityに入れれば、かなり良い感じになりそうです。

・ゲーム
ゲームの場合、状態をマシンAからBにポンと渡して引き続き遊べるのは魅力かもしれません。ただ、状態の区切りをどこに置くかという問題と、状態をUriとして一本にシリアライズできるのかという。Uri が長さどれくらいまで行けるのかはわかりませんが、あまり無理はしない方がいい気はします。

次の記事では、F10 を Windows Timeline 対応させた実作業の様子をコード例を挙げて書いてみます。

App を Windows Timeline に対応させる 2/2

2018年1月1日月曜日

あけましておめでとうございます

あけましておめでとうございます。
本年も宜しくお願い致します。

…この記事、あけおめの体で去年を振り返ろうという趣旨です。
昨年のトピックを発生順に並べてみますと…

Xamarin に手を出した  (2月)


Xamarin.Android を使ったApp Wheel World Clock for Android をリリースできました。
http://ddlgjp.blogspot.jp/2017/05/wheel-world-clock-android.html
元々はWin8/WinPhone8.1, UWP用に出していたアプリです。
F10 for Xamarin.Forms ...は少し動いた所で手が止まっています。無念。

Win10 Mobileを諦めた (4月)


Windows 10 Mobile について
http://ddlgjp.blogspot.jp/2017/04/windows-10-mobile.html
ムリダナ

Microsoft MVP for Windows Development を受賞した (6月)


(*´▽`*)ウラー 
http://ddlgjp.blogspot.jp/2017/06/microsoft-mvp-for-windows-development.html
受賞のベネフィット、特典には色々あるのですが、今の所一番楽しいのはMVP専用のメーリングリストです。濃い話がドコドコ流れてきてとても良いです。


ただ、後半は個人的な事、家族の事(故郷の父に介護が必要になるという…都会に出て働いてるおじさんなら誰もが通ると聞いてはいましたが私にも来ました。今は落ち着いておりますが)もあり、中々開発活動に力を入れられなかったなという所があります。

今年は…まずは3月にRedmond・Bellevue で開かれるMVP Global Summit に出られるのが楽しみです。また、Xamarin.Formsと.NET Core, serverでも遊びたいナーと思っています。