Realm Blog

Realm ObjC & Swift 2.4: オブジェクトレベルの通知

Realm Objective‑CおよびRealm Swift 2.4をリリースしました。 このバージョンには新機能としてオブジェクトレベルの通知が実装されました。各オブジェクトの更新をトリガーにした処理を書くことができるようになります。詳しくは下記をご覧ください。

オブジェクトレベルの通知

オブジェクトに変更があったことを通知するには、これまではコレクションの通知を利用する必要がありました。それによって、オブジェクトの追加削除、あるいは変更されたことを通知によって知ることができます。しかし、どのプロパティが変わったのかまではわかりませんでした。また、1つのオブジェクトに対する変更を通知したいだけなのに、コレクションを作り、非同期に監視するというのは面倒で、クエリとの相性もよくありませんでした。

単一のオブジェクトに対して、プロパティの変更を通知するには、KVOを使うこともできました。しかし、今となっては KVOはかなり古臭い仕組みであり、プロパティ1つ1つに対してKVOを設定しなければなりませんし、もちろん他のプラットフォームや言語で使うことはできません。またKVOによる通知は__同期的に__動作するので、UIスレッドをブロックしてしまうこともあります🙀。

本日リリースするオブジェクトレベルの通知では、1つのオブジェクトに対する変更をとても便利に監視できます。オブジェクト通知はコレクション通知と同様に、非常にシンプルなAPIで使えます。単に監視したいオブジェクトに通知ブロックを追加するだけです。通知が作成されると、NotificationTokenが返されるので、監視している間はトークンを保持するようにします。

通知が有効になると、変更があるたびに通知ブロックが呼ばれ、structのObjectChange引数によって、どのプロパティが変わったのか、またはオブジェクトが削除されたことを知ることができます。

class Message: Object {
  dynamic var isRead = false
  dynamic var content = ""
}

class MessageController: UIViewController {
  private let notificationToken: NotificationToken

  init(message: Message) {
    notificationToken = message.addNotificationBlock { change in
      switch change {
      case .change(let properties):
        if let readChange = properties.first(where: { $0.name == "isRead" }) {
          self.showReadBadge = readChange.newValue as! Bool
        }
        if let contentChange = properties.first(where: { $0.name == "content" }) {
          self.contentView.textValue = contentChange.newValue as! String
        }
      case .deleted:
        self.handleDeletion()
      case .error(let error):
        self.handleError(error)
      }
    }
  }

  deinit {
    notificationToken.stop()
  }
}

通知を停止するには、token.stop()メソッドを呼ぶか、トークンオブジェクトを解放します。

まとめると、Realmに保存されているオブジェクトに対してaddNotificationBlockを呼び、返ってきたNotificationTokenインスタンスを監視している間は保持します。通知ブロックの中で変更に対してリアクションします。

2点注意することがあります。List型のプロパティ(関連)が変更された場合は、newValueoldValueも渡ってきませんが、通知ブロックは呼び出されます。もし同期的にUIを更新したり、通知をスキップしたい場合はrealm.commitWrite(withoutNotifying: [token])を利用してUI駆動の書き込みテクニックを使用します。

不具合の修正

同期されたRealmを利用するとき、認証トークンを更新する際のエラーハンドリングの不具合を修正しました。 上記の問題のため、Realm Mobile Platformを利用している場合は、このバージョンにできるだけアップデートするようにしてください。

数か月もの間、頭を悩ませていたレースコンディション🏎によって”bad transaction log”の例外が発生する不具合も修正されています。

Swift 2サポートの削除

古いSwiftバージョンをサポートすることは__非常に__大変です😅。現在Swift 2.xを利用している開発者の割合は5%以下に満たないため、このバージョンからSwift 2.xはサポートされません。

つまりRealm Swift 2.3.0がSwift 2.xで使える最後のバージョンになります。ご不便をおかけしますが、ご了承ください。

Xcode 8.3 Beta 1について

先週Xcode 8.3 betaがリリースされました。Realm Objective-Cにコンパイルエラーが起こる問題がありましたが、すでに修正済みです。

しかし、Swift 3.1におけるコンパイルエラーの問題がまだ残っています。こちらのIssue#4586でXcode 8.3のサポートについて進捗を報告していますのでご覧ください。


お読みいただきありがとうございます。 Realm で素晴らしいアプリケーションを作りましょう!お困りの際はStack Overflow(日本語)Slack(日本語)Twitter(日本語)GitHub(英語)でご相談ください。


Realm Team

At Realm, our mission is to help developers build better apps faster. We provide a unique set of tools and platform technologies designed to make it easy for developers to build apps with sophisticated, powerful features — things like realtime collaboration, augmented reality, live data synchronization, offline experiences, messaging, and more.

Everything we build is developed with an eye toward enabling developers for what we believe the mobile internet evolves into — an open network of billions of users and trillions of devices, and realtime interactivity across them all.

記事の更新情報を受け取る