Slide 1

Slide 1 text

⚗ Reactive Programming with Realm

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

What is Realm & How does it work?

Slide 4

Slide 4 text

What is Realm not?

Slide 5

Slide 5 text

Realm is not an ORM. Realm is the database itself.

Slide 6

Slide 6 text

Embedded NoSQL Object-oriented Database

Slide 7

Slide 7 text

Embedded = Built from scratch for !

Slide 8

Slide 8 text

⚡ SQLite

Slide 9

Slide 9 text

NoSQL = Schema-free? No, too slow. !

Slide 10

Slide 10 text

Object-oriented

Slide 11

Slide 11 text

class Person : Object { dynamic var name = "" dynamic var age = 0 let children = List() let parents = LinkingObjects(fromType: Person.self, property: "children") }

Slide 12

Slide 12 text

You directly interact with memory-mapped data.

Slide 13

Slide 13 text

All retrieved objects are just pointers to their data. @interface RLMObjectBase () { realm::Row _row; } @end namespace realm { class Row { TableRef m_table; size_t m_row_ndx; } }

Slide 14

Slide 14 text

Their classes describe how to read from there and navigate within the file.

Slide 15

Slide 15 text

But let's take a closer look how the data structure looks like.

Slide 16

Slide 16 text

Realm !"" Versions !"" Tables !"" Columns !"" Values

Slide 17

Slide 17 text

The root level describes the different versions ! " #

Slide 18

Slide 18 text

ACID • Atomicity • Consistency • Isolation • Durability

Slide 19

Slide 19 text

Naïve

Slide 20

Slide 20 text

Multi Version Concurrency Control

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Copy-on-Write

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Live Objects class Message : Object { dynamic var text = "" } let realm = try! Realm() let feed = realm.objects(Message) feed.count // => 0 let hello = Message() hello.text = "Hello!" try! realm.write { realm.add(hello) } feed.count // => 1 !

Slide 27

Slide 27 text

Built-in Notifications • File-wide Observation • Fine-grained Notifications on Collections • Key-Value-Observing compliant

Slide 28

Slide 28 text

File-wide Observation // Observe Realm Notifications let token = realm.addNotificationBlock { notification, realm in viewController.updateUI() } // later token.stop()

Slide 29

Slide 29 text

Fine-grained Notifications let results = realm.objects(Person).filter("age > 5") // Observe Results Notifications notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in guard let tableView = self?.tableView else { return } switch changes { case .Initial: // Results are now populated and can be accessed without blocking the UI tableView.reloadData() break case .Update(_, let deletions, let insertions, let modifications): // Query results have changed, so apply them to the UITableView tableView.beginUpdates() tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic) tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic) tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, withRowAnimation: .Automatic) tableView.endUpdates() break case .Error(let error): // An error occurred while opening the Realm file on the background worker thread fatalError("\(error)") break } }

Slide 30

Slide 30 text

Key-Value-Observing func addObservers() { self.addObserver(self, forKeyPath: "entry.title", options: [], context: nil) self.addObserver(self, forKeyPath: "entry.date", options: [], context: nil) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer) { if keyPath == "entry.title" { self.textLabel!.text = entry.title } else if keyPath == "entry.date" { self.detailTextLabel.text = entry.date.description } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } }

Slide 31

Slide 31 text

Key-Value-Observing // e.g. with ReactKit (self.textLabel!, "text") <~ KVO.stream(self, "entry.title") (self.detailTextLabel!, "text") <~ KVO.stream(self, "entry.date") |> map { $0!.description as NSString }

Slide 32

Slide 32 text

Fundament for ⚗Reactive Apps

Slide 33

Slide 33 text

The Reactive Manifesto • Responsive • Resilient • Elastic • Message Driven

Slide 34

Slide 34 text

Demo

Slide 35

Slide 35 text

try! questions.map { try $0.answer() }

Slide 36

Slide 36 text

Thanks for your attention! @mrackwitz [email protected]