Jack of all trades

master of none. 多芸は無芸を地で行く、自作自演何でも屋。

Windows Phone8.1アプリでSQLiteを扱う

本エントリはWindows Phone / Windows 10 Mobile Advent Calendar 2015の10日目です。

www.adventar.org

今年のハイライトは何と言ってもMADOSMAの発売による国内Windows Phone端末の復活と、それを皮切りに始まったWindows 10 Mobile端末の開発発表ラッシュですね。 既に発売された端末も幾つかありますし、来年は本格的にWindows 10 Mobileが盛り上がる予感が高まってきました。

かく言う私も国内Windows Phone 8.1端末発売記念におでさん(@od_10z)主催で開催された「おでコン」なるアプリコンテストに memotchというアプリで参加させていただきました。詳細は以下の記事を参照。

Windows Phoneアプリ作りました - Jack of all trades
おでコンで入賞しました - Jack of all trades

このmemotchではActionを選択するタイルやタスクメモのデータ保存にSQLiteを使用しています。
ローカルに気軽に保存とはいえテキストで保存するのも味気ないので、何かしらDBに保存することを考えていたのですが、 残念ながらSQL Server Compactがオワコンの様なのでSQLiteを選択しました。 幸い.NETかつWindows Phone 8.1でSQLiteを扱う拡張機能やライブラリが一揃いしていたので、安心して利用することができました。 ということで、実際に使用した拡張機能やライブラリの紹介と簡単な使用方法についてまとめてみます。

1. SQLite for Windows Phone 8.1

何はなくとも、まずはこれを入れる必要があります。Windows Phone 8.1でSQLiteを扱うためのコンポーネント一式が含まれています。

visualstudiogallery.msdn.microsoft.com

Visual Studio拡張機能として用意されているので、Visual Studio上で「ツール」→「拡張機能と更新プログラム」を開いて オンライン検索するとすぐに見つかります。そのままサクッとインストール。

f:id:sadynitro:20151206233111p:plain

インストール後はプロジェクトの「参照の追加」から「拡張」の中にある「SQLite for Windows Phone 8.1」を選択して追加します。

f:id:sadynitro:20151206233247p:plain

1点注意なのですが、参照に追加した「SQLite for Windows Phone 8.1」に三角の警告マークが付いている場合があります。 SQLite for Windows Phone 8.1はビルドターゲットが「Any CPU」では使用できないため、デバッグ、リリース環境に応じて「x86」もしくは「ARM」を選択してください。
エミュレータの場合はPC上で動作するので大抵「x86」、実機の場合は「ARM」を選択することになると思います。

f:id:sadynitro:20151206233732p:plain

2. sqlite-net

.NETで扱えるSQLiteのORMです。こちらは必須ではありませんが、個人的には必須と言っておきたいライブラリです。

github.com

NuGetパッケージが用意されているのでこちらもVisual Studio上でサクッと導入できます。

f:id:sadynitro:20151206233848p:plain

sqlite-netをインストールすると以下のファイルがプロジェクトに追加されます。

f:id:sadynitro:20151206233936p:plain

3. 処理の実装

sqlite-netによるSQLiteデータベースの操作については、基本的にGitHubを参照していただければ問題ないかと思いますが、一応プロジェクトに組み込んだ場合の例を記載しておきます。

フレームワークなしはさすがに厳しいので、ここではPrismを使用します。(memotchもPrismを使用しています)

Windows Phone 8.1でPrismを扱う場合のあれこれはかずき先生(@okazuki)の記事を参考にすると良いかと思います。というかその一択かも。

blog.okazuki.jp

プロジェクト全体はGitHubを参照していただくとして、ここでは肝のModelとViewModelを抜粋して軽く説明しておきます。
モデルでは接続オブジェクトを作って、メソッドを呼ぶだけでテーブル作成や削除、レコードの挿入やクエリの実行ができることを確認しています。

// ListItemModel.cs
using SQLite;
using System.Collections.Generic;

namespace WindowsPhoneSampleApp.Models
{
  class ListItemModel
  {
    // SQLite接続オブジェクト
    private SQLiteConnection _db;

    // テーブルのスキーマ定義
    public class Items
    {
      [PrimaryKey, AutoIncrement]
      public int Id { get; set; }
      public string UserName { get; set; }
      public string Info { get; set; }
    }

    public ListItemModel()
    {
      var dbPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
      // DBファイルのパスをセット
      _db = new SQLiteConnection(dbPath + "/WPSampleApp");
      // Itemsテーブルを削除
      _db.DropTable<Items>();
      // Itemsテーブルを作成
      _db.CreateTable<Items>();

      // ダミーデータをセットする
      SetItems("hoge hoge", "Administrator");
      SetItems("huga huga", "Developer");
    }

    public void SetItems(string userName, string info)
    {
      // ユーザー名と情報を渡してItemsテーブルに挿入
      var ret = _db.Insert(new Items() { UserName = userName, Info = info });
    }
    
    public IEnumerable<Items> GetItems()
    {
      // クエリ文を実行
      return _db.Query<Items>("select * from Items order by Id;");
    }
  }
}

ViewModelではModelのメソッドを呼ぶことでデータを取得し、画面表示用のオブジェクトに詰め込んでいます。

// ListItemViewModel.cs
using System.Collections.Generic;
using WindowsPhoneSampleApp.Models;

namespace WindowsPhoneSampleApp.ViewModels
{
  class ListItemViewModel
  {
    private ListItemModel _listItemModel;

    public class Item
    {
      public int Id { get; set; }
      public string UserName { get; set; }
      public string Info { get; set; }
    }

    public IList<Item> ListItems { get; set; }

    // コンストラクタ
    public ListItemViewModel(ListItemModel listItemModel)
    {
      _listItemModel = listItemModel;

      ListItems = new List<Item>();
      var data = _listItemModel.GetItems();
      foreach (var d in data)
      {
        var temp = new Item();
        temp.Id = d.Id;
        temp.UserName = d.UserName;
        temp.Info = d.Info;
        ListItems.Add(temp);
      }
    }
  }
}

デバッグ実行するとこんな感じで表示されます。作成したItemsテーブルに挿入したダミーデータを取得して画面にバインドしています。

f:id:sadynitro:20151208211743p:plain

このように非常に簡単にSQLiteのDBを操作できます。

プロジェクト全体はこちらを参照。

sadynitro/SQLiteForWP · GitHub

(おまけ)UWPアプリでは?

ここまで読み進めて「で、UWPアプリの場合は?」と思っている方もいらっしゃるのではないでしょうか(それぐらい興味を持っていただいていると幸い)
実際にSQLiteを使用するUWPアプリを作成できているわけではないのですが、大体のアタリは付けています。

SQLite for Windows Phone 8.1」の代わりに「SQLite for Universal App Platform」なるものを、sqlite-netの代わりにSQLite.Net-PCLなるものが使えるようです。

SQLite for Universal App Platform
visualstudiogallery.msdn.microsoft.com

SQLite.Net-PCL
www.nuget.org

できれば近いうちにこれらを使用したUWPアプリサンプルもご紹介できればと思います。

まとめ

以上、私が実際にWindows Phone 8.1アプリを開発した際に利用した、SQLite関連の拡張機能やライブラリの紹介とその使用方法についてのまとめでした。 今後UWPアプリ開発が主流になると、OneDriveやAzureのストレージやSQL Databaseを利用してデスクトップアプリとモバイルアプリでデータ連携したりする仕組みが 大多数を占めてくるかもしれませんが、ローカルで軽量に設定情報を持たせたり、データを保持しておきたい場合はSQLiteを利用するのも一興かと。

明日のWindows Phone / Windows 10 Mobile Advent Calendar 2015 11日目は@_15cmさんです。よろしくどうぞ。