今回は、「お気に入り」に追加する機能だけを実装しよう。追加するのも、記事表示画面だけからとする。
エンドユーザーの操作としては、記事表示画面でアプリバーを出し、[お気に入りにする]ボタンをタップしてフライアウト(=ポップアップ)を出し、必要ならコメントを入力してから[追加]ボタンをタップするものとしよう(次の画像)。
その他、「お気に入り」に求められるスペックは次のようなものだ。
なお、「お気に入り」を削除/編集する機能や、メイン画面と一覧画面でも「お気に入り」にアクセスする機能も欲しくなるだろうが、本稿では扱わない(別途公開しているサンプルコードには削除機能も実装してあるので参考にしてほしい)。
「お気に入り」に追加する機能を実装するには、保持するデータの改修が必要になる。その上で、ロジックとUIを作り、最後にそれらを組み合わる。
データクラスを改修する
「お気に入り」として保持するデータには、1件の記事を表すFeedItemクラスのオブジェクトを使えばよさそうだ。ただし、スペックのところで述べたように、エンドユーザーが入力したコメントも保持したい。今回は、FeedItemクラスを改修して、コメントも保持できるようにしよう(次のコード)。
[System.Runtime.Serialization.DataContract]
public class FeedItem
{
……省略……
[System.Runtime.Serialization.DataMember]
public string FavoriteComment { get; set; }
}
これで、ダウンロードしたRSSフィードのデータと同様に「お気に入り」のデータも扱えるようになった。「お気に入り」のデータの1件はFeedItemオブジェクトとして、「お気に入り」のデータの全体はFeedオブジェクトとして表現できる。
「お気に入り」をファイルに読み書きするロジック
「お気に入り」のデータ(=Feedオブジェクト)を、アプリケーションデータ記憶域のファイルに書き出し、また読み込む機能が必要だ。そのような「お気に入り」のデータを管理するクラスを作る。プロジェクトのLogicフォルダーに新しいクラスを追加し、ファイル名を「FavoriteStorage.cs」とする。
FavoriteStorageクラスではWinRTのストリームと.NET Frameworkのストリームを変換することになる。変換のための拡張メソッドがWindowsRuntimeStreamExtensionsクラス(System.IO名前空間)にあるので、それを使えるようにusingの宣言を追加しておく(次のコード)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AtmarkItReader.DataModel;
using System.IO; // WindowsRuntimeStreamExtensionsを利用する
namespace AtmarkItReader.Logic
{
// 【第8回】「お気に入り」のデータを管理するクラス
public class FavoriteStorage
{
……省略……
「お気に入り」のデータを保存しておくファイルの名前は「Favorite.xml」としよう。保存するフォルダーは、アプリケーションデータ記憶域のローミングフォルダーとする。そして、保存するフォルダーのストレージオブジェクトをDataFolderというプロパティで参照できるようにしておこう(次のコード)。
public class FavoriteStorage
{
private const string FileName = "Favorite.xml";
private static Windows.Storage.StorageFolder DataFolder
{
get { return Windows.Storage.ApplicationData.Current.RoamingFolder; }
}
}
フォルダーを表すストレージオブジェクトのTryGetItemAsyncメソッドを使うと、フォルダー内のファイルやフォルダーを取得できる。次のコードのようにして、「Favorite.xml」ファイルのストレージオブジェクトを取得する。
public class FavoriteStorage
{
……省略……
internal static async Task<Windows.Storage.StorageFile> GetDataFileAsync()
{
return (await DataFolder.TryGetItemAsync(FileName)) as Windows.Storage.StorageFile;
}
}
「お気に入り」のデータをファイルから読み出してみよう。上のコードを使ってStorageFileオブジェクトが得られたら、そのOpenAsyncメソッドを呼び出すとWinRTのストリームが得られる。WindowsRuntimeStreamExtensionsクラスのAsStream拡張メソッドを使って、それを.NET Frameworkのストリームに変換する。今回は、XmlSerializerクラス(System.Xml.Serialization名前空間)を使って、そのストリームからFeedItemオブジェクトの配列にデシリアライズさせる(次のコード)。
public class FavoriteStorage
{
……省略……
internal static async Task<FeedItem[]> LoadAsync()
{
var file = await GetDataFileAsync(); // 「Favorite.xml」ファイルのストレージオブジェクトを取得
if (file == null)
return null;
try
{
using (var ras = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) // 読み込み専用としてストリームを開く
using (var stream = ras.AsStream()) // .NET Frameworkのストリームに変換
{
// ストリームからFeedItemオブジェクトの配列にデシリアライズ
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(FeedItem[]));
var feedItems = serializer.Deserialize(stream) as FeedItem[];
return feedItems;
}
}
catch
{
return null; // ファイルの読み込みやデシリアライズに失敗したときはnullを返す
}
}
}
次に、データの書き込みだ。ファイルに書き込むときには、ファイルが存在しなければ新たに作成する。すでにファイルが存在していたら、上書きする。フォルダーを表すストレージオブジェクトのCreateFileAsyncメソッドを使うと、そのような使い分けが引数で指定できる。CreateFileAsyncメソッドでStorageFileオブジェクトが得られたら、読み込みと同様な手順を踏んで.NET Frameworkのストリームを取得し、XmlSerializerクラスにシリアライズさせる(次のコード)。
public class FavoriteStorage
{
……省略……
private static async Task SaveAsync(FeedItem[] items)
{
try
{
var file = await DataFolder.CreateFileAsync(
FileName,
Windows.Storage.CreationCollisionOption.ReplaceExisting
// ↑ファイルがあれば上書き、無ければファイルを作成
);
using (var ras = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite)) // 読み書き用としてストリームを開く
using (var stream = ras.AsStream()) // .NET Frameworkのストリームに変換
{
// FeedItemオブジェクトの配列をシリアライズしてストリームに書き出す
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(FeedItem[]));
serializer.Serialize(stream, items);
}
}
catch { }
}
}
Copyright© Digital Advantage Corp. All Rights Reserved.