Entertainment Photoはアプリケーションストレージを使ってる

Entertainment Photoアプリテンプレートは、シナリオに基づいてグループや写真・図を追加できるアプリのテンプレートなんですが・・・

グループや項目を増減できるアプリのポイントって何?

それはね!!

何の仕掛けもなしにアプリが動いている間にグループ加えて、写真・図を加えて、アプリを終了したら…はい、次にアプリ起動したら元に戻りますよねぇ。そう、追加した情報をどこかに記録しておかないといけないんです。って事で、

アプリケーションストレージです。

Entertainment Photoアプリテンプレートでは、追加されたグループ、追加された写真・図をアプリケーションストレージに記録しています。アプリケーションストレージに関するコードは、DataModelフォルダーのPhotoDataAppStorage.csで実装されています。※このテンプレートはもとはグリッドアプリテンプレートです。SamleDataSource.csファイルは、感じを出すためにPhotoDataSource.csと名前を変えています。

WinRT APIでは、My Documentsなどの一部のフォルダーを除き、ファイルのパスを指定してファイルを作成したりファイルのストリームを開いたりできません。また、My Documents以下でも、どこにアプリ向けのフォルダーを作ればよいか、決めるのは結構難しいので、アプリの設定やファイルは、アプリケーションストレージを使いましょう。

Entertainment Photoでは、キーとバリューで管理するLocalSettingsと、ファイルを格納するLocalFolderを使っています。どちらの機能も、Windows.Storage名前空間のApplicationDataクラスを使います。

先ず、LocalSettingsの使い方です。

アプリケーションのLocalSettingsの参照方法は、

    var localSettings = ApplicationData.Current.LocalSettings;

です。localSettingsは、ValuesとContainersの二つのプロパティを持っています。単にあるキーに対する値を格納したいだけであれば、

    string key = "...";
    string value = "...";
    localSettings.Values.Add(key, value);

これで、keyに対応してvalueを関連付けて保存できます。値は数字でもOKです。keyに対する値の参照は、

    string value = localSettings.Value[key] as string;

です。valueが単純な値ならこれでいいのですが、グループやアイテムといった複数のプロパティの組を保存したい場合は、ApplicationDataCompositeValueを使います。

    PhotoDataGroup group = ...;
    var composite = new ApplicationDataCompositeValue();
    composite["Title"] = group.Title;
    composite["Subtitle"] = group.Subtitle;
    composite["ImagePath"] = group.ImagePath;
    composite["Description"] = group.Description;
    appSettings.Values.Add(key, composite);

これで登録完了。参照は、

    var stored = appSettings.Values[key] as ApplicationDataCompositeValue;

です。一つ注意が必要なのは、取り出したApplicationDataCompositeValueの値を更新してもそのままではアプリケーションストレージには反映されない点です。値を更新するには

    var stored = appSettings.Values[key] as ApplicationDataCompositeValue;
    stored["Description"] = "....";
    appSettings.Values[key] = stored;

と更新したApplicationDataCompositeValueを再代入してください。また、登録したKey Valueペアを削除したい場合は、基本型の場合もCompositeの場合も、Removeメソッドを使います。

    appSettings.Values.Remove(key);

 次に、ファイルの保存です。このテンプレートは、FilePickerでユーザーがピクチャフォルダー等から選択した写真をアプリに”追加”できますが、同じアプリを追加した場合、編集機能追加などで登録された写真を個別に変更することを想定して、都度別ファイルとしてアプリのストレージフォルダーに格納しています。ファイルをアプリケーションストレージに格納するには、ApplicationData.Current.LocalFolderを使います。サブフォルダーやファイルの作成が可能です。
画像ファイル格納用フォルダーは、

    // フォルダー名を指定してフォルダーを取り出す
    var folder = await Application.Current.localFolder.GetFolderAsync(folderName);
    if (folder == null)
    {
        // フォルダーを作る
        folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(folderName, CreationCollisionOption.OpenIfExists);
    }

こんな感じで作ります。ファイルの取り出しは、

    var file = await folder.GetFileAsync(fileName);

ファイルのコピーは、

    var copyFile = await folder.CopyAsync(folder, newName);

ファイルの削除は、

    file.DeleteAsync(StorageDeleteOption.PermanentDelete);

ファイルからストリームを取り出すには、

    var stream = await file.OpenAsync(FileAccessMode.Read);

などです。フォルダーやファイルに関するメソッドは全て非同期です。上に示したようにawaitをつけるなどして、非同期プログラミングを行ってください。

ファイルを開くにはフォルダーへの参照が必要です。ユーザーの操作を伴わずにフォルダーの参照が取得できるのは、Windows.Storage.KnownFoldersから取得できるPictureLibrary等か、アプリケーションストレージの下のフォルダーだけです。 ローカルにファイルを保存する場合には、そこを踏まえて保存場所を考えましょう。

アプリを拡張する場合には、ファイルをネットワーク上(SkyDrive等)におくのもよいでしょう。PhotoDataSource.csで定義されているPhotoDataItemやPhotoDataGroupにプロパティを追加する場合には、PhotoDataAppStorage.cs内でLocalSettingsに保存するKey、Valueを追加してください。