Realm Xamarin メモ[Xamarin.Forms]
RealmのXamarin版が5/10に出ました。今回はそれを弄ってみたのでメモ等をつらつらと書いていきます。
Realmとは
詳しいことは
を見てみてください。
シンプル!!早い!!クロスプラットフォーム!!先進的!!など魅力的な言葉が踊っています。これはぜひ試すしかないでしょう。
なおUWP(とMac)は今のところ非対応ですが将来的に対応したいとのことなので近いうちにサポートされるでしょう(願望)。(realm-dotnetのIssueには既にUWPサポートの声がたくさん)
Realm Browser
Realmのデータベースのデータがどうなってるか知りたいとき、MacユーザにはRealm Browserという便利なものが用意されています。
Realm Browser
ScreenShotの言語は英語なのに入力が日本語なのめっちゃ気になる
使い方は簡単でRealmファイルをダブルクリックして出てきたウインドウのAllowボタンを押すだけです。データが可視化されてしかも編集もできるので大変便利です。
(iOS SimulatorでRealmファイルの場所がわからない場合は
swift - Realm Browserの使い方 - スタック・オーバーフロー
をみれば大丈夫かも)
ただ、上のリンクのバージョンだと一度開くとRealm Xamarinで開けなくなります。(2016/5/17現在) なのでRealm Xamarinで使いたい人はGithubから直接ダウンロードしてきましょう。
インストール
さっそく使っていきましょう。 準備はとても簡単でVSの場合ソリューションを右クリック->Manage Nuget Packages for Solution...でRealmを検索してプロジェクト全てにチェックをした状態でインストールするだけ。とても簡単です。(Versionは0.74.1)
さあ、早速iOSでビルドしてみると・・・
失敗しましたorz
原因
どうやらRealmはiOS7以上が必要な模様。VSのXamarin PCLで作るとiOSのデフォルトターゲットは6なので7以上に上げる必要があるみたいです。 なのでiOSの場合はiOSのプロジェクトを右クリック->Properties->iOS ApplicationのDeployment Targetを適宜変更しましょう。
Androidも変える必要があるかもしれませんが残念ながらAndroidエミュレータは永眠中なので確かめられません。
もう一度ビルドしてみると成功しました!
使ってみる
それでは早速使っていきましょう。
Realmを使うのに各プロジェクトにそれぞれPath等を書く必要はありません。デフォルトでは'Environment.SpecialFolder.Personalに作られるみたいです(ファイル名はdefault.realm)。名前を変更したい場合は
Realm.GetInstance(optionalPath)`のoptionalPathに好きな名前を入れましょう。
今回はお試しなので適当にテーブル作ってデータ突っ込んで取得して画面に表示させます。
public App() { //Realmインスタンス取得 var realm = Realm.GetInstance(); //書き込み開始 using (var transaction = realm.BeginWrite()) { var sample = realm.CreateObject<Human>(); sample.Age = 18; sample.Name = "Hoge hoge"; transaction.Commit(); } //テーブルの一番最初のデータ取得 var human = realm.All<Human>().ToList().FirstOrDefault(); var content = new ContentPage { Title = "RealmSample", Content = new StackLayout { VerticalOptions = LayoutOptions.Center, Children = { new Label { HorizontalTextAlignment = TextAlignment.Center, Text = $"名前:{human.Name}\n年齢:{human.Age}才", } } } }; MainPage = new NavigationPage(content); } public class Human : RealmObject { public int Age { get; set; } public string Name { get; set; } }
実行してみると・・・
無事に追加されています。やったね!
realm.All<Human>()
で直接FirstOrDefault()しない理由はまだサポートされてないのでToListを挟まないと使えないからです。ただ、PullRequestも飛んでたし次のバージョンくらいにはサポートされるんじゃないかなーと期待してます。
なお現時点でもFirstメソッドは使えます。
注意点
実際に使ってみてハマったところや気になったところ
使えるデータ
Realmがサポートしているのは
- bool
- char
- byte
- short
- int
- long
- float
- double
- string
- DateTimeOffset
です。プリミティブ型はNullableもサポートしています。また、RealmObjectとRealmListも設定可能です。
Linqサポート
上にも書きましたが、まだLinqの全てのメソッドをサポートしたわけでは無いみたいです。私が知っているのはFirstOrDefaultとSingleOrDefault、Take、Where系の中でRealmObjectのプロパティ同士の比較(.Where(x=>x.Name==otherX.Name)
)とか。.Where(x=>x.Name=="Hoge")
は大丈夫)です。(他にもありそう)
Transaction外でプロパティセット
上の例でもそうですが、using(var tansaction=realm.BeginWrite())
の外でRealmオブジェクトを通して取得したRealmObjectオブジェクトのプロパティのセッターを呼ぶと死にます。
なのでMVVMパターンでうっかりViewModelのプロパティにRealmObjectを紐付けて双方向バインディングで更新をしようとしたら例外で即死します。
ObjectId
特筆すべきことではないっぽいのですが、主キーを設定したいときはObjectId属性をつけるとそうなります。 個人的にそういうのはPrimaryKeyって感じなので最初戸惑ったのですが他でもそう呼ばれているらしい?