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

The Challenges of Building a Database API (in Swift)

The Challenges of Building a Database API (in Swift)

Presented at 360i|Dev 2015.

Samuel E. Giddins

August 18, 2015
Tweet

More Decks by Samuel E. Giddins

Other Decks in Technology

Transcript

  1. Realm — Fast, zero-copy, embedded database built from the ground

    up for mobile — Used in apps with hundreds of millions of users — NoSQL (as in, no SQL) — Fully ACID transactions — Well-defined threading model — Cross-platform C++ core with many language bindings (currently Objective-C, Swift, & Android)
  2. Databases Defined by a few different questions: — What's the

    atomic unit? — How do you interact with your data? — What's implicit? What's explicit? — What do you optimize for? — Performance — Code — Safety — Concurrency
  3. Databases So much is about the API. Implementing the storage

    engine is hard enough, but it's the easy part.
  4. Databases — Are at the center of almost every mobile

    app. — They're used everywhere in an app. — Perhaps the cornerstone.
  5. Existing Approaches — Core Data — sqlite.h — Redis —

    SQL — ActiveRecord — Sequel — Realm Objective-C
  6. Swift Features — Optionals — Generics & Type Inference —

    Enums — Structs / Value Types — Static Compiler ✨
  7. Realm Objective-C Features — Swizzling — Runtime introspection — Laziness

    — Autoreleasepool-based caching — Native "dynamic" API — On-demand class creation
  8. Sacrifices — Type safety — String — AnyObject — Queries

    — Struct value semantics — Non-RawRepresentable enums — Error handling
  9. class Book: Object { dynamic var name = "" //

    needs default for schema initialization dynamic var pageCount: Int = 0 dynamic var author: Author? override class func primaryKey() -> String { return "name" } } let realm = Realm() let books = realm.objects(Book).filter("pageCount > 50").sort("name") let book = Book(value: ["name" : "The Name of the Wind"]) book.author = books.filter("name = %@", "The Wise Man's Fear").first?.author book.pageCount = 994 realm.write { realm.add(book) realm.create(Book.self, book, update: true) }
  10. let realm = Realm() var writeTransaction = realm.beginWrite() let table

    = writeTransaction.table(Book) writeTransaction.set(table, 0, Book.Properties.Name, "Catch-22") realm.commitWrite(writeTransaction)
  11. let book = Book() book.name = "Cien Años de Soledad"

    book.pageCount = 324 do { let realm = try Realm() realm.write { realm.add(book, update: true) } } catch { // handle error }
  12. Dynamic — Normally means slow — Slower than static —

    Faster than string-based lookups — Flexible — Can bind to column indices at runtime — Allows for "standalone" objects
  13. Dynamic — Limited to "Objective-C types" — No List<Book> —

    No Int? — No String? — Yes Author? — Requires var — Can be lying to the compiler — No way to enforce — Confusing when a property isn't persisted
  14. book.name = book.name + ": Part Deux" => — Load

    book name — Translate to NSString — Append — Store new book name
  15. Testing — Handling failure modes — Code that shouldn't compile

    — Using generics — Looks nothing like user code
  16. !

  17. ! — CocoaPods — Carthage — Module Maps — Nested

    Frameworks — Xcodes & Swift Versions — Documentation
  18. The Verdict — Nicest Realm API yet — Least cooperative

    language — Relying on interop is !/" — Prototype something else — Eventually
  19. The Verdict What's Missing — Native metaprogramming — Dynamic structs

    — API / ABI / Tooling -- stability / compatibility — C++ interop — Property properties — Threading in the type system
  20. Yet

  21. Give us one or two more features, and a few

    years, and Swift could give us the perfect platform for building expressive, concise, powerful, & performant APIs.