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
型のプロパティ(関連)が変更された場合は、newValue
もoldValue
も渡ってきませんが、通知ブロックは呼び出されます。もし同期的に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(英語)でご相談ください。