アクティベーションURIの設計
「タイムライン」を利用するアプリを作るにあたって最も難しいのは、このURIの設計なのですが、その方法はここでは省略します。プロトコルアクティベーションで起動されたときにアプリの状態を復元するにはどうしたらよいか、しっかり検討する必要があります。
サンプルコードはごく簡単なWebブラウザなので、アプリの状態はそのときに表示していたWebページのURLだけで決まるものとします。そこで、アクティベーションURIは次のようにしてみました。
uf05.bluewatersoft.jp-timelinetest://url?{URL}
スキーム(プロトコル名):uf05.bluewatersoft.jp-timelinetest
ホスト名:url
パス:(なし)
クエリ(「?」マーク以降):クエリ全体でWebページのURL
プロトコルアクティベーションで起動されたときは、渡されたアクティベーションURIのクエリ部分から「?」マークの後ろを取り出すとWebページのURLになっているので、そのWebページを表示すれば以前の状態が復元できるというわけです。
スキーム(プロトコル名)は、すべて小文字にしなければなりません。英字で始まり、英数字と「-」や「.」などが使えます。
「ユーザーアクティビティ」を登録する方法
「タイムライン」に「ユーザーアクティビティ」を登録する最小限の手順は、次のようになります。
- アクティビティIDを決定する:「ユーザーアクティビティ」、つまり「タイムライン」上のカードを識別するためのIDです。任意の文字列です
- UserActivityChannelからUserActivityを得る:既存のアクティビティIDなら取得、そうでなければ新規オブジェクト生成になります
- ActivationUriをセット:アクティベーションURIを組み立ててUserActivityにセットします
- DisplayTextをセット:「タイムライン」のカードに表示される文字列をUserActivityのVisualElementsにセットします
- UserActivityを保存します
- UserActivitySessionを作って保持します:これを行わないと「タイムライン」に表示されません
ここでアクティビティIDは、「タイムライン」がカードを識別するためのものです。「タイムライン」は同じカード(=アクティビティIDが同じ「ユーザーアクティビティ」)であっても、登録した時刻ごとに表示します。同じアクティビティIDで3回登録すれば、同じカードが3枚表示されるわけです。また、「タイムライン」上で削除すると同じカードは全て消えます。そのような性質を考慮して、アクティビティIDの生成方法を決めてください。今回は、表示しているWebページのURLそのものをアクティビティIDとしました。
UserActivityChannelからUserActivityを得るときに、アクティビティIDを渡します。すでに登録済みのアクティビティIDだったときは、既存のUserActivityオブジェクトが返ってきます。その場合は、UserActivityオブジェクトの各プロパティに既存のデータが入っています。初めてのアクティビティIDを渡したときは、新しく生成されたUserActivityオブジェクトが返ってきます。既存か新規かの区別は、取得したUserActivityオブジェクトのStateプロパティで分かります。
UserActivityを保存するたびに、UserActivitySessionを(既存のオブジェクトは破棄して)新しく作って保持しておく必要があります。
上記の手順を実際に記述すると次のコードのようになります。
// UserActivitySession を保持するためのメンバ変数
private UserActivitySession _userActivitySession;
public async Task AddToTimelineAsync(string url)
{
string activityId = url; //ここでは URL を Activity ID とする
// UserActivityChannel から UserActivity を生成する (登録済みなら取得になる)
var userActivityChannel = UserActivityChannel.GetDefault();
UserActivity userActivity
= await userActivityChannel.GetOrCreateUserActivityAsync(activityId);
// タイムラインから呼び出されるときのアクティベーション URI をセット
// (ただし、登録済みのアクティビティではセット済み。変更不要なのでセットしない)
if (userActivity.State != UserActivityState.Published)
userActivity.ActivationUri = new Uri($"uf05.bluewatersoft.jp-timelinetest://url?{url}");
// タイムラインに表示される文字列をセット (タイムライン上での検索対象)
// (これも以前と同じでよければ、登録済みのアクティビティではセット不要)
userActivity.VisualElements.DisplayText = $"UF05 {DateTime.Now.ToString("HH:mm:ss")}";
// UserActivity を保存
await userActivity.SaveAsync();
// 以前の UserActivitySession があるなら破棄して、新しいセッションを保持
_userActivitySession?.Dispose();
_userActivitySession = userActivity.CreateSession();
}
あとは適切なタイミングで上のメソッドを呼び出してあげるだけです。このサンプルでは、Webページの表示に成功したときに呼び出すようにしました(⇒MainPage.xaml.csのWebView1_NavigationCompletedメソッド)。
このコードで「タイムライン」に登録したカードの例を示します(次の画像)。
まっ黒な背景に文字列が表示されているだけのごくシンプルなものですが、「タイムライン」に表示できました! 背景に色を付けたり、画像を埋め込んだりする方法は、後ほど説明します。
