Slide 1

Slide 1 text

Welcome to the Real Reactive World Realm World Tour, Seoul, 2017 Sangjoon Moon

Slide 2

Slide 2 text

Erik Meijer GOTO 2015 One Hacker Way https://www.youtube.com/watch?v=FvMuPtuvP5w

Slide 3

Slide 3 text

When you want to stay up to date, push not pull Erik Meijer

Slide 4

Slide 4 text

Pull Driven • Too Fast • The Wrong Moment • Slow https://dribbble.com/shots/2141820-Latest-News-Pull-to-Refresh

Slide 5

Slide 5 text

Push Driven https://dribbble.com/shots/1473664-Android-Wear-Clock-App-GIF

Slide 6

Slide 6 text

Push Driven Real-time Data Sync • Realm Mobile Platform • Google Firebase Real-time Database

Slide 7

Slide 7 text

How It Works(Clients) • Authentication • Configuration • Data Sync

Slide 8

Slide 8 text

Authentication(Realm) private var user: SyncUser? func logIn(completion: ((Void)->Void)? = nil) { // You can use SyncUser.current to check logged in user guard user == nil else { completion?() return } let credentials = SyncCredentials.usernamePassword(username: username, password: password) SyncUser.logIn(with: credentials, server: authServerURL) { (user, error) in if let user = user { self.user = user DispatchQueue.main.async { completion?() } } else if let error = error { // handling the error properly } } } Tracking Santa With Realm https://realm.io/news/track-santa-with-realm-swift-database-platform-part-3/

Slide 9

Slide 9 text

Configuration(Realm) // opening a standalone Realm let realm = try! Realm()

Slide 10

Slide 10 text

Configuration(Realm) // Create the configuration for the synced Realm let syncServerURL = URL(string: "realm://localhost:9080/~/ userRealm")! let config = Realm.Configuration(syncConfiguration: SyncConfiguration(user: user, realmURL: syncServerURL)) // Open the remote Realm let realm = try! Realm(configuration: config)

Slide 11

Slide 11 text

Configuration Wrapper(Realm) // SantaRealmManager.swift private func realm(for user: SyncUser?, at syncServerURL: URL) -> Realm? { guard let user = user else { return nil } let syncConfig = SyncConfiguration(user: user, realmURL: syncServerURL) let config = Realm.Configuration(syncConfiguration: syncConfig) guard let realm = try? Realm(configuration: config) else { fatalError("Could not load Realm") } return realm } Tracking Santa With Realm https://realm.io/news/track-santa-with-realm-swift-database-platform-part-4/

Slide 12

Slide 12 text

Configuration Wrapper(Realm) private let realmManager = SantaRealmManager() realmManager.logIn { if let realm = self.realmManager.santaRealm() { let santas = realm.objects(Santa.self) … } } // SantaRealmManager.swift func santaRealm() -> Realm? { return realm(for: user, at: santaRealmURL) } Tracking Santa With Realm https://realm.io/news/track-santa-with-realm-swift-database-platform-part-4/

Slide 13

Slide 13 text

Data Sync(Realm) • Notification(Realm, Collection, Object) • KVO

Slide 14

Slide 14 text

Data Sync(Realm) // Object Notifications var token : NotificationToken? // change is the type of enum. token = stepCounter.addNotificationBlock { change in switch change { case .change(let properties): // PropertyChange is the type of struct for property in properties { if property.name == "steps" && property.newValue as! Int > 1000 { print("Congratulations, you've exceeded 1000 steps.") token = nil } } case .error(let error): print("An error occurred: \(error)") case .deleted: print("The object was deleted.") } }

Slide 15

Slide 15 text

Configuration(Firebase) // application:didFinishLaunchingWithOptions: // Initialize Firebase FIRApp.configure() // Firebase Console // Rules to restrict to authenticated users for the path `messages` { "rules": { "messages": { ".read": "auth != null", ".write": "auth != null" } } }

Slide 16

Slide 16 text

By default, read and write access to your database is restricted so only authenticated users can read or write data. Firebase Docs https://firebase.google.com/docs/database/ios/read-and-write

Slide 17

Slide 17 text

Authentication(Firebase) // google account sign in func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) { if let error = error { print("Error \(error)") return } guard let authentication = user.authentication else { return } let credential = FIRGoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken) FIRAuth.auth()?.signIn(with: credential) { (user, error) in if let error = error { print("Error \(error)") return } } }

Slide 18

Slide 18 text

Data Sync(Firebase) var ref: FIRDatabaseReference! fileprivate var _refHandle: FIRDatabaseHandle? func updateUI() { ref = FIRDatabase.database().reference() // Listen for new messages in the Firebase database _refHandle = self.ref.child("condition").observe(.value, with: { [weak self] (snapshot) -> Void in guard let strongSelf = self else { return } strongSelf.conditionLabel.text = snapshot.value as? String }) } deinit { // If an observer isn't properly removed, it continues to sync data to local memory if let refHandle = _refHandle { ref.child("condition").removeObserver(withHandle: refHandle) } } Firebase Database Demo https://www.youtube.com/watch?v=joVi3thZOqc

Slide 19

Slide 19 text

ROS / Firebase • Data Structure(Realm Model / JSON) • Hosting Types • Server Event Handling • Dashboard • Offline Capabilities

Slide 20

Slide 20 text

Summary • Push Driven • Auth, Config, Data Sync • Build Better Apps Faster

Slide 21

Slide 21 text

Questions? Sangjoon Moon [email protected] dakeshi@github