Xamarin.FormsでRealm Xamarinを使ってみました。
プロジェクトを作成する
適当にプロジェクトを作成します。
UIを整える
ボタンをタップされたら、押されたタイミングの時刻(時分秒)をRealmに登録して、さらにListViewに表示させたいと思います。
RealmSamplePage.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:RealmSample" x:Class="RealmSample.RealmSamplePage"> <ContentPage.Padding> <OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" /> </ContentPage.Padding> <StackLayout Orientation="Vertical"> <StackLayout Orientation="Horizontal"> <Label Text="Welcome to Xamarin Forms!" /> <Button Text="Add" Clicked="AddAction" /> </StackLayout> <ContentView HeightRequest="1" BackgroundColor="Black" /> <ListView x:Name="listView" /> </StackLayout> </ContentPage>
RealmSamplePage.xaml.cs
ボタンが押されたらAddAction
が呼ばれます。
using Xamarin.Forms; namespace RealmSample { public partial class RealmSamplePage : ContentPage { public RealmSamplePage() { InitializeComponent(); } void AddAction(object sender, System.EventArgs e) { // throw new NotImplementedException(); } } }
実行してみました。適当にこんな感じにしました。
Realm Xamarinをインストールする
Realmをインストールします。iOSのプロジェクトではPodfileに書いて、Androidのプロジェクトではgradleに追記してインストールしました。
XamarinではNugetを使ってインストールします。
[Add Package]ボタンをクリックしてインストールします。
PCL側だけではなく、RealmSample.DroidとRealmSample.iOSのプラットフォームにもパッケージを追加しておきます。
Itemクラスを作る
Realmのデータベースに格納するオブジェクトのクラスを作成します。
なんでも良いのですがここではItemクラス
を作成しました。TimeString
にボタンをクリックした時刻を格納しようと思います。
using System; using Realms; namespace RealmSample { public class Item : RealmObject { public string TimeString { get; set; } } }
RealmSamplePage.xaml.cs
ボタンが押されるとAddActionメソッド
が実行されます。このメソッドの中でRealmへの追加とListViewのデータソースの追加を行いました。
using Xamarin.Forms; using Realms; using System.Collections.ObjectModel; using System; using System.Linq; namespace RealmSample { public partial class RealmSamplePage : ContentPage { ObservableCollection<string> items = new ObservableCollection<string>(); public RealmSamplePage() { InitializeComponent(); listView.ItemsSource = items; } void AddAction(object sender, System.EventArgs e) { var time = DateTime.UtcNow.ToString("HH:mm:ss"); // RealmにItemオブジェクトを追加する var realm = Realm.GetInstance(); realm.Write(() => { realm.Add(new Item { TimeString = time }); }); // ListViewの先頭にも時刻を表示させる items.Insert(0, time); } } }
一度アプリをkillして、再度立ち上げると今までRealmに追加したはずのデータが表示されていません。PageのコンストラクタでRealmからItemオブジェクトを取り出してListViewに表示されるようにしました。
using Xamarin.Forms; using Realms; using System.Collections.ObjectModel; using System; using System.Linq; namespace RealmSample { public partial class RealmSamplePage : ContentPage { ObservableCollection<string> items = new ObservableCollection<string>(); public RealmSamplePage() { InitializeComponent(); // Realmから登録されたItemオブジェクトを取り出してソートする var realm = Realm.GetInstance(); var allItems = realm.All<Item>().OrderByDescending((arg) => arg.TimeString); // データソースに時刻を追加する foreach (var i in allItems) { items.Add(i.TimeString); } listView.ItemsSource = items; } void AddAction(object sender, System.EventArgs e) { // RealmにItemオブジェクトを追加する var realm = Realm.GetInstance(); realm.Write(() => { realm.Add(new Item { TimeString = time }); }); // ListViewの先頭にも時刻を表示させる items.Insert(0, time); } } }
トラブルシューティング
このボタンを押すとItemを追加するだけのサンプルアプリを書いている時にもいくつか問題が発生しました。
実行時に例外が発生してしまう
RealmSamplePageのコンストラクタにvar realm = Realm.GetInstance();
の1行を追加すると、実行時に例外が発生してしまいました。
System.IO.FileNotFoundExceptionがスルーされました
Could not load file or assembly 'Realm, Version=0.81.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
実行するプラットフォーム(この場合はRealmSample.iOS)のパッケージにもRealmをインストールする必要がありました。