12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

.NET MAUI (データストア)

Last updated at Posted at 2022-06-28

.NET MAUI のデータストア

.NET MAUIのデータストアはどうなってるのかな?
とういうことで、勉強していきます。

開発環境

  • Win11
  • VS2022 Preview Version 17.3.0 Preview 2.0

環境構築&プロジェクト作成の流れはこちらの記事でどうぞ。

サンプルソース

.NET MAUIの新規プロジェクト作成時のサンプルソースです。
画面上のボタンをクリックするとその回数をお知らせします。
悲しいことに、クリック回数を永続化しません。
2,147,483,647回クリックしても、アプリケーション閉じたら1からやり直しです。しないけど。

MainPage.cs

namespace MauiDatabaseDemo;

public partial class MainPage : ContentPage
{
	int count = 0;

	public MainPage()
	{
		InitializeComponent();
	}

	private void OnCounterClicked(object sender, EventArgs e)
	{
		count++;

		if (count == 1)
			CounterBtn.Text = $"Clicked {count} time";
		else
			CounterBtn.Text = $"Clicked {count} times";

		SemanticScreenReader.Announce(CounterBtn.Text);
	}
}

データを保存する方法

クリック回数を是が非でも永続したいんじゃっ!てことで、.NET MAUI でデータを永続する方法調べました。

  1. Preferences
  2. FileSystem
  3. Database
  4. Remote (この記事ではあつかいません。)
  5. SecureStorage 2022/07/19追加

1. Preferences

key=value形式で値を永続することができます。
値としてサポートされるのは

  • Boolean
  • Double
  • Int32
  • Single
  • Int64
  • String
  • DateTime

です。
複雑なデータには向きません。Jsonにシリアライズして・・・とか考えないように。

ソース

では、クリック回数を永続してみましょう!

namespace MauiDatabaseDemo;

public partial class MainPage : ContentPage
{
	int count = 0;

	public MainPage()
	{
		InitializeComponent();
	}

	private void OnCounterClicked(object sender, EventArgs e)
	{
		// ADD START
		count = Preferences.Get("count", 0); // 第二引数はデフォルト値
        // ADD END

        count++;

		if (count == 1)
			CounterBtn.Text = $"Clicked {count} time";
		else
			CounterBtn.Text = $"Clicked {count} times";

		SemanticScreenReader.Announce(CounterBtn.Text);

        // ADD START
        Preferences.Default.Set("count", count);
        // ADD END
    }
}

どこに保存されるか?

  • iOS : NSUserDefaults
  • Android : SharedPreferences
  • Windows : ApplicationDataContainer
    C:/Users/UserId/AppData/Local/Packages/ApplicationIdGuid_xxxxxxxxxxxxx/Settings/settings.dat ぽい。

2. FileSystem

アプリケーション専用のディレクトリであれば、権限を気にせずアクセス可能です。
※iOSな人は、うんたらかんたら書いてあったので、参考資料を見れ。

// アプリケーションデータはこっち
string mainDir = FileSystem.Current.AppDataDirectory;
// キャッシュデータはこっち
string cacheDir = FileSystem.Current.CacheDirectory;

ソース

では、クリック回数を永続してみましょう!
よい子は、Serializerとか使いましょう()

namespace MauiDatabaseDemo;

public partial class MainPage : ContentPage
{
	int count = 0;

	public MainPage()
	{
		InitializeComponent();
	}

	private void OnCounterClicked(object sender, EventArgs e)
	{
		// ADD START
		string path = Path.Combine(FileSystem.Current.AppDataDirectory, "count.txt");
		if (File.Exists(path))
		{
			using (var s = new StreamReader(File.OpenRead(path)))
			{
				count = int.Parse(s.ReadLine());
			}
		}
		else
		{
			count = 0;
		}
        // ADD END

        count++;

		if (count == 1)
			CounterBtn.Text = $"Clicked {count} time";
		else
			CounterBtn.Text = $"Clicked {count} times";

		SemanticScreenReader.Announce(CounterBtn.Text);

        // ADD START
        using (var s = new StreamWriter(File.OpenWrite(path)))
        {
			s.Write(count.ToString());
        }
        // ADD END
    }
}

どこに保存されるか?

  • Windows :
    C:/Users/UserId/AppData/Local/Packages/ApplicationIdGuid_xxxxxxxxxxxxx/LocalState/count.txt

3. Database

「この要件で、DBなしの設計なんてムリポぉ!」な時がくるかもしれないし。
参考資料sqlite-net-pcl 押しなので、使ってみましょう。

EF.Coreダメなん? (未調査)
SQLite専用だけど、EF.Coreと操作感は似てました。
個人的にtransactionをusingできないのが違和感。

ソース

では、クリック回数を永続してみましょう!
無駄にクリックした日時も記録しちゃいますよ!無駄に!

using SQLite;

namespace MauiDatabaseDemo;

public partial class MainPage : ContentPage
{
	int count = 0;

	private SQLiteConnection conn;

	public MainPage()
	{
		InitializeComponent();

        // ADD START
        string path = Path.Combine(FileSystem.Current.AppDataDirectory, "count.db3");
		conn = new SQLiteConnection(path);
        // conn = new SQLiteAsyncConnection(path) 非同期版
		conn.CreateTable(typeof(ClickTime));
        // ADD END
    }

    private void OnCounterClicked(object sender, EventArgs e)
	{
		// ADD START
		count = conn.Table<ClickTime>().Count();		
        // ADD END

        count++;

		if (count == 1)
			CounterBtn.Text = $"Clicked {count} time";
		else
			CounterBtn.Text = $"Clicked {count} times";

		SemanticScreenReader.Announce(CounterBtn.Text);

		// ADD START
		try
		{
			conn.BeginTransaction();
			conn.Insert(new ClickTime() { Time = DateTime.Now });
			conn.Commit();
		}
		catch
		{
			conn.Rollback();
		}
        // ADD END
    }
}

[Table(nameof(ClickTime))]
public class ClickTime
{
	[PrimaryKey]
	[Column(nameof(Time))]
	public DateTime Time { get; set; }
}

どこに保存されるか?

当然ながらFileSystemと同じ。

4. SecureStorage 2022/07/19追加

セキュリティで保護されたストレージだそうです。
認証キーとか、抜かれて困るものがあれば。
string型しか対応していません。

ソース

// 設定
await SecureStorage.Default.SetAsync(string key, string value);

// 取得
await SecureStorage.Default.GetAsync(string key);

// 削除
await SecureStorage.Default.Remove(string key);

// すべて消す
SecureStorage.Default.RemoveAll();

参考資料

MS様に感謝☆

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?