Skip to content

Instantly share code, notes, and snippets.

@mbalex99
Last active July 28, 2017 20:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbalex99/b3cd03e3d01d1644153893366d054e76 to your computer and use it in GitHub Desktop.
Save mbalex99/b3cd03e3d01d1644153893366d054e76 to your computer and use it in GitHub Desktop.
Observing and Writing to Real-time Offline First Realm
import UIKit
import RealmSwift
class Doctor: Object {
dynamic var _id: String = ""
dynamic var name: String = ""
dynamic var address: String = ""
dynamic var updatedOn: NSDate = NSDate()
}
class MyDoctorsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
lazy var tableView: UITableView = {
let t = UITableView()
return t
}()
var token: NotificationToken?
var results: Results<Doctor>?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
title = "My Doctors"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "New Doctor", style: .done, target: self, action: #selector(MyDoctorsViewController.addANewDoctor))
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .done, target: self, action: #selector(MyDoctorsViewController.clearButtonDidClick))
view.addSubview(tableView)
tableView.frame = self.view.frame
tableView.delegate = self
tableView.dataSource = self
let syncConfig = SyncConfiguration(user: SyncUser.current!, realmURL: URL(string: "realm://localhost:9080/~/mydoctors")!)
let realm = try! Realm(configuration: Realm.Configuration(syncConfiguration: syncConfig))
results = realm.objects(Doctor.self)
token = results?.addNotificationBlock { [weak self] (changes) 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.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
with: .automatic)
tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
with: .automatic)
tableView.endUpdates()
break
case .error(let error):
// An error occurred while opening the Realm file on the background worker thread
fatalError("\(error)")
break
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell()
let doctor = results![indexPath.row]
cell.textLabel?.text = "\(doctor.name) \(doctor.location)"
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results?.count ?? 0
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let results = results, let token = token else { return }
let item = results[indexPath.row]
let realm = results.realm!
realm.beginWrite()
realm.delete(item)
tableView.deleteRows(at: [indexPath], with: .fade)
try! realm.commitWrite(withoutNotifying: [token])
}
}
deinit {
token?.stop()
}
func clearButtonDidClick(){
let realm = results!.realm!
try! realm.write {
realm.delete(self.results!)
}
}
func addANewDoctor(){
let syncConfig = SyncConfiguration(user: SyncUser.current!, realmURL: URL(string: "realm://localhost:9080/~/myDoctors")!)
let realm = try! Realm(configuration: Realm.Configuration(syncConfiguration: syncConfig))
let newDoctor = Doctor()
newDoctor.name = "Some name"
newDoctor.location = "Some address"
newDoctor.updatedOn = Date()
try! realm.write {
realm.add(newDoctor)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment