Slide 1

Slide 1 text

Realm meetup #17 [email protected]

Slide 2

Slide 2 text

Katsumi Kishikawa Realm Inc. [email protected]

Slide 3

Slide 3 text

Recent Updates [email protected]

Slide 4

Slide 4 text

Recent Updates • Realm Objective-C/Swift 1.0.2 (was 1.0.1) • Realm Java 1.1.0 (was 1.0.1) • Realm React Native 0.14.0 (was 0.13.0) • Realm Xamarin 0.76.0 [email protected] [email protected]

Slide 5

Slide 5 text

Realm Objective-C/Swift 1.0.2 (was 1.0.1) [email protected]

Slide 6

Slide 6 text

Realm Objective-C/Swift 1.0.2 • ϓϩύςΟ͕ଘࡏ͠ͳ͍ΫϥεΛอଘ͠Α͏ͱ͢Δͱྫ֎ʹ • write(_:)ϝιουͷϒϩοΫ಺ͰthrowͰ͖ΔΑ͏ʹ • όΠφϦαΠζ͕গ͠ݮগ • addNotificationBlock(_:, change:)Ͱॳճͷݺͼग़͠͸ඞ ͣ.Initial͕ݺ͹ΕΔΑ͏ʹ • ٯํ޲ͷؔ࿈͕มߋʹͳΔ৔߹ʹ௨஌͕ݺ͹Εͳ͍໰୊Λमਖ਼ [email protected] [email protected]

Slide 7

Slide 7 text

Already compatible with Swift 3 & Xcode 8 https://github.com/realm/realm-cocoa/issues/3796 [email protected]

Slide 8

Slide 8 text

Protip for Xcode 8 beta3 and Carthage [email protected] $ echo SWIFT_VERSION=\"3.0\">swift3.xcconfig $ XCODE_XCCONFIG_FILE=`pwd`/swift3.xcconfig \ carthage update --platform iOS --no-use-binaries

Slide 9

Slide 9 text

RxSwift & Realm [email protected]

Slide 10

Slide 10 text

What’s Rx? [email protected]

Slide 11

Slide 11 text

What’s Rx? [email protected] [1, 2, 3, 4, 5, 6]

Slide 12

Slide 12 text

What’s Rx? [email protected] [1, 2, 3, 4, 5, 6] .filter { $0 % 2 == 0 }

Slide 13

Slide 13 text

What’s Rx? [email protected] [1, 2, 3, 4, 5, 6] .map { $0 * 5 }

Slide 14

Slide 14 text

What’s Rx? [email protected] Array => Observable

Slide 15

Slide 15 text

RxRealm https://github.com/RxSwiftCommunity/RxRealm [email protected]

Slide 16

Slide 16 text

Using RxRealm [email protected] pod 'RxSwift' pod 'RxCocoa' pod 'RealmSwift' pod 'RxRealm'

Slide 17

Slide 17 text

RxRealm makes Realm observable [email protected] Realm.asObservable() Results.asObservable() List.asObservable() LinkingObjects.asObservable() AnyRealmCollection.asObservable()

Slide 18

Slide 18 text

RxRealm makes Realm observable [email protected] Results.asObservableArray() List.asObservableArray() LinkingObjects.asObservableArray() AnyRealmCollection.asObservableArray()

Slide 19

Slide 19 text

RxRealm makes Realm observable [email protected] Realm.asObservableChangeset() Results.asObservableChangeset() List.asObservableChangeset() LinkingObjects.asObservableChangeset() AnyRealmCollection.asObservableChangeset()

Slide 20

Slide 20 text

RxRealm makes Realm observable [email protected] Realm.asObservableChangesetArray() Results.asObservableChangesetArray() List.asObservableChangesetArray() LinkingObjects.asObservableChangesetArray() AnyRealmCollection.asObservableChangesetArray()

Slide 21

Slide 21 text

RxRealm makes Realm observable [email protected] Realm.rx_add() Realm.rx_delete()

Slide 22

Slide 22 text

RxRealm makes Realm observable [email protected] public func asObservable() -> Observable { return Observable.create {observer in let token = self.addNotificationBlock {changeset in let value: Self switch changeset { case .Initial(let latestValue): value = latestValue case .Update(let latestValue, _, _, _): value = latestValue case .Error(let error): observer.onError(error) return } observer.onNext(value) } return AnonymousDisposable { observer.onCompleted() token.stop() } } }

Slide 23

Slide 23 text

RxRealm makes Realm observable [email protected] public func asObservable() -> Observable { return Observable.create {observer in let token = self.addNotificationBlock {changeset in let value: Self ... observer.onNext(value) } return AnonymousDisposable { observer.onCompleted() token.stop() } } }

Slide 24

Slide 24 text

RxRealm makes Realm observable [email protected] public func asObservable() -> Observable { return Observable.create {observer in let token = self.addNotificationBlock {changeset in let value: Self ... observer.onNext(value) } return AnonymousDisposable { observer.onCompleted() token.stop() } } }

Slide 25

Slide 25 text

RxRealm makes Realm observable [email protected] public extension NotificationEmitter where Self: RealmCollectionType { public func asObservable() -> Observable { return Observable.create {...} } }

Slide 26

Slide 26 text

RxRealm makes Realm observable [email protected] public protocol NotificationEmitter { func addNotificationBlock(block: (RealmCollectionChange) -> ()) -> NotificationToken } extension List: NotificationEmitter {} extension AnyRealmCollection: NotificationEmitter {} extension Results: NotificationEmitter {} extension LinkingObjects: NotificationEmitter {}

Slide 27

Slide 27 text

RxRealm makes Realm observable [email protected] public extension NotificationEmitter where Self: RealmCollectionType { public func asObservable() -> Observable { return Observable.create {...} } }

Slide 28

Slide 28 text

Usage [email protected] var token: NotificationToken? func searchWithText(text: String) { token = realm .objects(Location) .filter("...") .sorted("...") .addNotificationBlock { (...) in ... tableView.reloadData() } ... }

Slide 29

Slide 29 text

Usage [email protected] realm .objects(Location) .filter("address CONTAINS %@", query) .sorted("identifier") .asObservable() .subscribeNext {[unowned self]results in ... }.addDisposableTo(self.bag)

Slide 30

Slide 30 text

Example [email protected] /* Observable> - wrap Results as observable */ realm.objects(Lap).asObservable() .map {laps in "\(laps.count) laps"} .subscribeNext {[unowned self]text in self.title = text } .addDisposableTo(bag) /* Observable> - convert Results to Array and wrap as observable */ realm.objects(Lap).sorted("time", ascending: false).asObservableArray() .map {array in array.prefix(5) } .bindTo(tableView.rx_itemsWithCellIdentifier("Cell", cellType: UITableViewCell.self)) {row, element, cell in cell.textLabel!.text = formatter.stringFromDate(NSDate(timeIntervalSinceReferenceDate: element.time)) }.addDisposableTo(bag) /* Use bindable sinks to add objects */ addOneItemButton.rx_tap .map { Lap() } .bindTo(Realm.rx_add()) .addDisposableTo(bag) addTwoItemsButton.rx_tap .map { [Lap(), Lap()] } .bindTo(Realm.rx_add()) .addDisposableTo(bag)

Slide 31

Slide 31 text

Incremental search [email protected] class ViewController: UIViewController, UISearchBarDelegate, UITableViewDataSource { ... func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return results.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { cell = ... item = results[indexPath.row] cell.textLabel.text = ... return cell } func searchWithText(text: String) { realm .objects(Location) .filter("...") .sorted("...") .addNotificationBlock { (...) in ... } ... tableView.reloadData() } func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { ... searchWithText(text) return true }

Slide 32

Slide 32 text

Incremental search [email protected] class ViewController: UIViewController { let bag = DisposeBag() let realm = try! Realm() @IBOutlet weak var searchBar: UISearchBar! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() searchBar .rx_text .subscribeNext { [unowned self] (query) in self.realm .objects(Location) .filter("address CONTAINS %@", query) .sorted("identifier") .asObservable() .bindTo(self.tableView.rx_itemsWithCellIdentifier("Cell", cellType: UITableViewCell.self)) {( cell.textLabel!.text = element.address self.tableView.reloadData() }.addDisposableTo(self.bag) } .addDisposableTo(bag) }

Slide 33

Slide 33 text

Where to find us • ! Realm Japan User Group: facebook.com/groups/realmjp • ! Twitter: twitter.com/realmJapan • GitHub: github.com/realm • ! StackOverflow: ja.stackoverflow.com/questions/tagged/realm • ! Email: [email protected] • ! Slack: slack.realm.io/ [email protected] [email protected]

Slide 34

Slide 34 text

Realm Japan User Group Facebook [email protected]

Slide 35

Slide 35 text

Support Chat Slack [email protected]

Slide 36

Slide 36 text

Ξϯέʔτ http://bit.ly/RealmJP_17 [email protected]

Slide 37

Slide 37 text

Questions? Katsuma Kishikawa [email protected] www.realm.io/jp @k_katsumi