Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Using Realm with Swift

Using Realm with Swift

Realm is a new mobile database that is an alternative to Core Data. This is a brief introduction to using Realm with Swift, including notes on how to install it and some gotchas you might run into when you begin using Realm.

Feihong Hsu

March 10, 2015
Tweet

More Decks by Feihong Hsu

Other Decks in Programming

Transcript

  1. Using Realm with Swift CocoaHeads March 10, 2015 Feihong Hsu

    github.com/feihong © Feihong Hsu, 2015 1
  2. What is Realm? Realm is a mobile database for iOS

    and Android. On iOS, it's meant to be a replacement for Core Data, offering a similar API but with better performance and a smaller footprint. © Feihong Hsu, 2015 2
  3. Installing in your project Three methods: • CocoaPods • Carthage

    • Manual installation (supports iOS 8 dynamic frameworks) © Feihong Hsu, 2015 3
  4. Installing to a Swift project using CocoaPods The latest stable

    release of CocoaPods doesn't support Swift packages, so you need to install the prelease version: gem install cocoapods --pre © Feihong Hsu, 2015 4
  5. Installing to a Swift project using CocoaPods In your Podfile,

    you should force the Realm pod to be installed as a framework: platform :ios, '8.0' use_frameworks! pod 'Realm' © Feihong Hsu, 2015 5
  6. Installing to a Swift project using CocoaPods (2) If you

    don't add use_frameworks!, you must create a bridging header for Realm. You also need to add the RLMSupport.swift file into your project. © Feihong Hsu, 2015 6
  7. Loading your Realm database in the browser To find the

    location of your Realm database file, run this code in your program: println(RLMRealm.defaultRealm().path) Then run something like this: open /Users/fhsu/Library/Developer/CoreSimulator/Devices/.../default.realm © Feihong Hsu, 2015 8
  8. Creating a model Just subclass RLMObject and add some properties:

    class Product: RLMObject { dynamic var name = "" dynamic var price = 0.0 dynamic var rating = -1 dynamic var startDate = NSDate(timeIntervalSince1970: 0) } © Feihong Hsu, 2015 9
  9. Limitation: incomplete support for optionals This does NOT work: class

    Product: RLMObject { // ... dynamic var startDate: NSDate? } One possible workaround is to wrap the object inside an RLMObject subclass. © Feihong Hsu, 2015 10
  10. Wrapping an object inside RLMObject You can define a DateBox

    class that subclasses RLMObject and has a single property of type NSDate: class DateBox: RLMObject { dynamic var value = NSDate(timeIntervalSince1970: 0) } © Feihong Hsu, 2015 11
  11. Wrapping an object inside RLMObject (2) Now you can do

    this: class Product: RLMObject { // ... dynamic var startDate: DateBox? } © Feihong Hsu, 2015 12
  12. Gotcha: Custom initializers for RLMObject subclasses If you want to

    make a custom initializer you'll first need to add this annoying boilerplate to your class definition: override init() { super.init() } override init(object: AnyObject!) { super.init(object:object) }; override init(object: AnyObject!, schema: RLMSchema!) { super.init(object: object, schema: schema) } override init(objectSchema: RLMObjectSchema) { super.init(objectSchema: objectSchema) } © Feihong Hsu, 2015 13
  13. Adding objects to the database // Using an Array: Product.createInRealm(realm,

    withObject: ["Sais", 44.87, 5, NSDate()]) // Using a Dictionary: Product.createInDefaultRealmWithObject( ["name": "Sais", "price": 44.87, "rating": 5, "startDate": NSDate()]) // Using a custom initializer: realm.addObject(Product( name: "Sais", price: 44.87, rating: 5, startDate: "2013-02-28")) © Feihong Hsu, 2015 14
  14. All writes to the database must be inside a transaction

    realm.beginWriteTransaction() // write some data realm.commitWriteTransaction() realm.transactionBlock { // write some data } © Feihong Hsu, 2015 15
  15. Gotcha: one-liners in [RLMRealm transactionBlock:] You might need to add

    a return statement inside the closure: RLMRealm.defaultRealm().transactionWithBlock { Product.createInDefaultRealmWithObject( [name, 0.0, 3, NSDate()]) return } © Feihong Hsu, 2015 16
  16. Subscribing to database changes let realm = RLMRealm.defaultRealm() self.notificationToken =

    realm.addNotificationBlock { notification, realm -> Void in self.tableView.reloadData() } © Feihong Hsu, 2015 17
  17. Notifications • There's no way to be notified of a

    particular type of database write. • The notification is automatically deleted whenever the notification token goes out of scope. For this reason, you'll often want to make the notification token object a property of your view controller. © Feihong Hsu, 2015 18
  18. Gotcha: retain cyles in [RLMRealm addNotificationBlock:] let realm = RLMRealm.defaultRealm()

    self.notificationToken = realm.addNotificationBlock { [weak self] // avoid retain cycle notification, realm -> Void in self.tableView.reloadData() return } © Feihong Hsu, 2015 19
  19. Pros • Free, even for commercial projects • Simpler API

    than Core Data • Open source (partly) • Nice database browser © Feihong Hsu, 2015 20
  20. Cons • Still beta (currently at version 0.90.6) • Swift

    API is a work-in-progress • Support for optionals is not great • No fine-grained notifications (also no support for KVO) © Feihong Hsu, 2015 21
  21. Conclusion Realm is a bit immature right now as it

    heads toward its first stable release. But you should give Realm a try if your app's model isn't too hindered by the current limitations. http://realm.io © Feihong Hsu, 2015 24