[Xamarin.Forms] Properties Dictionaryを使ってデータを永続化する

[Xamarin.Forms] Properties Dictionaryを使ってデータを永続化する

Clock Icon2017.03.01

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは。モバイルアプリサービス部の加藤 潤です。 今回はXamarin.Formsでデータを永続化する仕組みであるProperties Dictionaryを使ってみました。

検証環境

  • Xamarin Studio Community バージョン 6.2(build 1821)
  • Xamarin.Forms バージョン 2.3.3.193

実行結果

先に実行結果を載せておきます。 iOSは10.2のシミュレーター、Androidは実機(Androidバージョン6.0.1のNexus 5)で動かしています。

 iOS  Android
iOS_Properties_Dictionary Android_Properties_Dictionary

簡単にアプリの説明をすると、
アプリを起動するとテキストを入力するコントロールと、Saveボタンが表示されます。
テキストを入力し、Saveボタンをタップすると入力したテキストが永続化されます。
アプリを再起動した時に永続化されたデータを取得し、ラベルに表示しています。

ソースコード

アプリの初期ページであるAppClassFeaturePageのXAMLは以下のようにしました。

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AppClassFeature" x:Class="AppClassFeature.AppClassFeaturePage">
    <StackLayout VerticalOptions="Center">
        <Entry x:Name="Entry" Placeholder="保存するテキストを入力してください。" HorizontalOptions="Center" Margin="20"></Entry>
        <Button x:Name="SaveButton" Text="Save" HorizontalOptions="Center" Clicked="Handle_Clicked"></Button>
        <Label x:Name="Label" Text="" HorizontalOptions="Center"></Label>
    </StackLayout>
</ContentPage>

また、コードビハインドは以下のように実装しました。

public partial class AppClassFeaturePage : ContentPage
{
    private const string PropertyKeyMyText = "myText";

    public AppClassFeaturePage()
    {
        InitializeComponent();

        // 保存されているテキストをラベルに表示
        UpdateLabelText();
    }

    void Handle_Clicked(object sender, System.EventArgs e)
    {
        // 保存
        Application.Current.Properties[PropertyKeyMyText] = this.Entry.Text;

        // 保存されているテキストをラベルに表示
        UpdateLabelText();
    }

    private void UpdateLabelText()
    {
        if (Application.Current.Properties.ContainsKey(PropertyKeyMyText))
        {
            this.Label.Text = Application.Current.Properties[PropertyKeyMyText] as string;
        }
    }
}

データの保存は

Application.Current.Properties[PropertyKeyMyText] = this.Entry.Text;

保存したデータの取得は

Application.Current.Properties[PropertyKeyMyText] as string;

で行なっています。非常に簡単ですね!

データが保存されるタイミング

Application.Current.Propertiesにキーと値をセットすればデータは自動的に保存されるのですが、保存タイミングは即時ではないようです。iOSで確認した結果、データはボタンをタップしたタイミングではなく、ホームボタンをタップしてアプリがバックグラウンドに移行したタイミングで保存されていました。

即時保存したい場合はキーと値をセットした後、Application.Current.SavePropertiesAsync();を呼ぶようにしてください。

データはどこに保存されるのか

データがどこに保存されるのか気になったので調べてみました。

iOS

iOS(シミュレーター)の場合は以下の場所に保存されていました。

/Users/<ユーザー名>/Library/Developer/CoreSimulator/Devices/<デバイスID>/data/Containers/Data/Application/<アプリID>/Documents/.config/.isolated-storage/PropertyStore.forms

以下はファイルをAtomで開いた結果です。ちゃんと指定したキーと値が保存されていることが確認できました。

@ArrayOfKeyValueOfstringanyType9http://schemas.microsoft.com/2003/10/Serialization/Arrays i)http://www.w3.org/2001/XMLSchema-instance@KeyValueOfstringanyType@Key�myText@Value.type�a:string   a http://www.w3.org/2001/XMLSchema�This is test data

Android

Androidは以下の場所に保存されていました。

/data/data/<アプリのパッケージ名>/files/.config/.isolated-storage/PropertyStore.forms

ファイルの内容はiOSと同じでした。

@ArrayOfKeyValueOfstringanyType9http://schemas.microsoft.com/2003/10/Serialization/Arrays i)http://www.w3.org/2001/XMLSchema-instance@KeyValueOfstringanyType@Key�myText@Value.type�a:string   a http://www.w3.org/2001/XMLSchema�This is test data

Xamarin Studioからは以下の手順でAndroid実機のアプリ内に保存されたファイルにアクセスできました。

  1. Xamarin Studioの「ツール」からSDK Command Promptを起動
  2. adb shell
  3. run-as <アプリのパッケージ名>
  4. cat files/.config/.isolated-storage/PropertyStore.forms

ちなみに

Xamarinのソースコードは公開されているので、Properties Dictionaryがどのような実装になっているかは以下を覗いてみるといいと思います。筆者も覗いてみて、

「ふむふむ、CoreでDependencyService使ってる!」→「ということは実装は各プラットフォーム毎にありそう」→「あった!」という感じで読むことができました。

おわりに

今回はProperties Dictionaryを使ってiOS、Androidそれぞれでデータを保存してみました。 iOSのUserDefaultsやAndroidのSharedPreferencesとは異なる場所、ファイル名で永続化されることがわかりました。 また、データは暗号化などはされずそのまま保存されるので、パスワードなどは保存しないようにしましょう。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.