post Image
2017年版Realmのエレガントな使い方

はじめに

Realmと言えば、とにかく高速なモバイルDBという感じでしたが、最近では「双方向編集」、「リアルタイム同期」など、公式サイトのキャッチフレーズも変わってきてます。2017年版のハマりポイントと、エレガントな使い方のパターンの紹介です

1.検索してから更新する

下記のように、RLMResultsをインスタンス変数に持った状態で、HogeHogeオブジェクトを追加すると、resultsに自動的に追加されます。

self.results = HogeHoge.allObjects()

// 適当にオブジェクトを生成
 let realm = RLMRealm.default()
 try realm.transaction {
    let hoge = HogeHoge()
    realm.addOrUpdate(draft)
 }

self.results.count // 増えてる

逆に、トランザクションの直後に再度取得した場合、反映されないことがありました。

 let realm = RLMRealm.default()
 try realm.transaction {
    let hoge = HogeHoge()
    realm.addOrUpdate(draft)
 }
let results = HogeHoge.allObjects() //書いたオブジェクトがない!!!!

またRLMResultsには更新された際に、発火するブロックを追加できます。

let token = results.addNotificationBlock({[weak self] (results, change, error) in
}

まとめると、Realmで更新直後に、更新内容を含む、データを取得したい場合は

// 1.検索する
self.results = HogeHoge.allObjects()


// 2.更新された際のブロックを追加

self.results.addNotificationBlock({[weak self] (results, change, error) in

}

// 3.更新する
 let realm = RLMRealm.default()
 try realm.transaction {
    let hoge = HogeHoge()
    realm.addOrUpdate(draft)
 }

とするとできます。

2.TableView/CollectionView パターン

TableViewとCollectionViewの場合の実装パターンです

1.viewDidLoadで、RLMResultsをインスタンス変数に持ち、更新フックで、reloadDataを呼び出します

override func viewDidLoad() {
   self.datas = HogeHoge.allObjects() 
   self.datas.addNotificationBlock({[weak self] (results, change, error) in
      self.collectionView.reloadData()
   }
}

2.DataSourceで、RLMResultsを使って、行数を返します

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
   return self.datas.count
}

このように実装すると、データが更新された際に、ビューが自動的に更新されます。

3.PageViewControllerパターン

1ページを表すUIViewControllerにRLMObjectをコピーしたstructを作成し、structのインスタンスを変数として持ちます。RLMObjectを直接保持すると、そのRLMObjectが削除された後に、変数にアクセスするとAssertionErrorが発生します。

class FooViewController: UIViewController {
   var hoge: HogeHogeWrapper!
}

次にDataSourceクラスにて下記のように実装します。

var datas: RLMResults<RLMObject>

override init() {
   datas = HogeHoge.allObjects()
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

   //UIViewControllerから現在のオブジェクトを取得
   guard let hoge  = (viewController as? FooViewController)?.hoge else { return nil }

   //indexを求める
   let index = indexOf(medium: hoge)
   if index <= 0 { return nil}

   //隣のオブジェクトをセットする
   controller.hoge = datas.object(at: (index-1)) as! Hoge
   return controller
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
   guard let hoge  = (viewController as? FooViewController)?.hoge else { return nil }
   let index = indexOf(medium: hoge)
   if (index+1) >= datas.count { return nil }
   controller.hoge = datas.object(at: (index+1)) as! Hoge
   return controller 
}

今のコントローラの持つ、オブジェクトを元に、RLMResultsのindexを求めることで、データが追加された際に、自動的に追従できるようになります。ただしこのままでは、ページ1とページ2がある場合に、データがページの間に追加された場合に、追従しないため更新フックを使って、ページビューを再作成する必要がありますが、大体のケースでは機能します。

現場からは以上です。


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。