loading...
Cover image for iOS Database Comparison. What are the differences?

iOS Database Comparison. What are the differences?

apentsov profile image Alexander Pentsov ・7 min read

Introduction

When developing iOS applications, it is often necessary to store, search and filter data, and the best way to do that is to use a database. The task of choosing the most suitable database for your application is very important and your choice may very depending on the complexity and amounts of data you want to manage. It is important to make this choice wisely, because if the choice was poor and short-sighted - you might run into the problem of reimplementing the data persistence logic in your application which may increase the development costs.
The most popular options of managing datastore in an iOS application are:

  1. SQLite, a lightweight and simple database management system (also used by Core Data by default)
  2. Core Data, a native iOS framework from Apple.
  3. Realm, a modern third-party database with its own engine.
  4. Firebase, a cloud-hosted alternative to traditional databases.

Alt Text

Let’s have a look at what each solution offers us.


SQLite

Let’s start with the most popular option, SQLite.
SQLite is the most used database management system in the world. It does not need any additional configuration or a server. This database was created in far 2000. It is free and open source. The particularity of SQLite is that It doesn’t use server-client architecture and it allows developers to store the app on a mobile device. That is why so many developers use it when they need all information to be stored on a device without the necessity to use a server.
The native API looks dated (C-style syntax) but there are tons of wrapper libraries for SQLite, which makes using it for data storage very simple. Here’s a code sample using the GRDB.swift library:

// Modify the database:
try dbQueue.write { db in
    try db.create(table: "place") { ... }
    try Place(...).insert(db)
}

// Read values:
try dbQueue.read { db in
    let places = try Place.fetchAll(db)
    let placeCount = try Place.fetchCount(db)
}

Compare that to the native SQLite3 C-style syntax:

// Modify the database
var insertStatement: OpaquePointer?
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
    let id: Int32 = 1
    let name: NSString = "Test"
    sqlite3_bind_int(insertStatement, 1, id)
    sqlite3_bind_text(insertStatement, 2, name.utf8String, -1, nil)
    if sqlite3_step(insertStatement) == SQLITE_DONE {
        print("\nSuccessfully inserted row.")
    } else {
      print("\nCould not insert row.")
    }
  } else {
    print("\nINSERT statement is not prepared.")
  }
  sqlite3_finalize(insertStatement)

Sum up of SQLite features:

  • Most used database management system in the world. This means that most developers have experience with it and that it is widely supported and is available on virtually any platform.
  • Very lightweight and performant. Performance has become a crucial factor for great user experience when developing iOS apps.
  • Very simple to set up and use. You can start using SQLite in your app very quickly without any additional setup.
  • Native syntax looks dated but there are a lot of wrapper libraries available.

Core Data

First of all, Core Data is not a database. Core Data was designed as a framework for managing an object graph, rather than a framework for storing data. Therefore, storing data is just one of the features of Core Data and it is not the most important one. Core Data uses SQLite database by default as storage but theoretically any SQL database can be used, although that would require implementing the data persistence functionality from scratch.
Core Data does a lot more than simply reading and writing data, it has a lot of additional features like change tracking, data versioning, automatic validation, advanced undo/redo functionality etc.
With great power comes great learning curve, so Core Data is not that easy to set up. You need to understand its rather inconvenient API to make use of the framework. If you are using Core Data for simple reading and writing data on/off a disk, you are misusing the framework since there are much better options for that.

// Read with Core Data: 
do {
  let request: NSFetchRequest<Category> = Category.fetchRequest()
  categories = try context.fetch(request)
} catch {
  print("Error fetching data from context: \(error)")
}

// Delete with Core Data: 
let request: NSFetchRequest<Item> = Item.fetchRequest()
let categoryPredicate: NSPredicate = NSPredicate(format: "parentCategory.name MATCHES %@", categoryName)
let itemPredicate: NSPredicate = NSPredicate(format: "title MATCHES %@", itemName)
request.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [categoryPredicate, itemPredicate])

if let results = try? context.fetch(request) {
  for object in results {
    context.delete(object)
  }
  // Save the context and delete the data locally
  itemArray.remove(at: indexPath.row)
  do {
    try context.save()
  } catch {
    print("Error saving context: \(error)")
  }
}    

Sum up of Core Data features:

  • Core Data is not a database. It is a framework for managing an object graph.
  • Has a lot of additional features. If you don’t need any of it’s features, you’re better off using a different database solution.
  • Has a learning curve. You have to get used to the framework to make use of its features, but once you get the hang of it, it’s going to be worth it.
  • Very useful when you have to manage a lot of complex objects and relations between them.

Realm

Realm is a NoSQL database that makes it possible for programmers to declare relationships between objects, as developers can do it in object graph of any programming language.
Realm uses its own engine that was designed specifically to run on phones, tablets and wearables. It is cross-platform so it can be used for both iOS and Android. This can save you time implementing storage layer in your application, since same Realm objects can be used on all available platforms. Realm is somewhat similar to Core Data in terms of it being an object store rather than a traditional table-based database.
Realm is a lot faster than SQLite when it comes to fetching data.

Alt Text
Alt Text

Realm also works on live data rather than copies of data. This means that when we modify the objects from our queries the changes are reflected in the database immediately. If we were using SQLite, we would get a copy of the data we fetched from the database and we would have to write it back to the database to save the changes. Realm is a third-party dependency and a dependency for such a core functionality as data storage has its risks.

Realm’s syntax is much more concise than Core Data. Consider this example and compare it to the Core Data example above.

// Read with Realm:
categories = realm.objects(Category.self)
categories = realm.objects(Category.self).sorted(byKeyPath: "name", ascending: true)

// Delete with Realm: 
do {
  try realm.write {
    realm.delete(todoItems![indexPath.row])
  }
} catch {
  print("Error deleting item from Realm: \(error)")
}

Sum up of Realm features:

  • A modern database designed specifically for mobile applications.
  • A lot easier to learn than CoreData. Syntax is modern and concise.
  • Cross-platform for iOS and Android. Same models can be reused on both platforms.
  • More performant than CoreData and SQLite when it comes to querying.

Firebase Realtime Database

Firebase Realtime Database is an alternative to traditional databases. It is an efficient, low-latency cloud-hosted database, where data is represented in JSON format rather than in tables. It was one of the first JSON database solutions at the time, providing easy to use interface for storing and synchronizing the data.
The difference between Firebase and aforementioned solutions is that Firebase is a cloud-hosted service, meaning that the data will be available to all of your users over the Internet, while the aforementioned solutions are made for storing data locally.
Firebase has a free plan that would be sufficient to get up and running with your application.
Realtime Database is only one of the many features of Firebase, others being Authorization, Push Notifications, Storage, Analytics etc. Realtime Database is a good choice when you can make use of Firebase’s other features or when you don’t want to bother incorporating a traditional database management system.

Firebase also has simple syntax:

// Write data
var ref: DatabaseReference!
ref = Database.database().reference()
self.ref.child("users").child(user.uid).setValue(["username": username])

// Read data
let userID = Auth.auth().currentUser?.uid
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
  // Get user value
  let value = snapshot.value as? NSDictionary
  let username = value?["username"] as? String ?? ""
  let user = User(username: username)

  // handle user
  }) { (error) in
    print(error.localizedDescription)
}

Sum up of Firebase Realtime Database features:

  • Simplest backend-as-a-service with database features.
  • Realtime Database is an online hosted database, which means you can synchronize data between users without setting up a server.
  • Database structure is simple and is represented as a JSON tree.
  • It is very simple to set up and use. Syntax is easy to learn.

Conclusion

There are tons of other third-party database management systems available, but the ones listed here are the most popular and most of the problems you might run into were likely solved before.

SQLite is the most widely used database engine in the world but it is pretty old and its functionalities are rather simple. Syntax shows its age but wrapper libraries are there for you.

Core Data has a lot of advanced features way beyond simple reading and writing operations but it comes with a price of additional complexity and a learning curve.

Realm has a huge advantage over Core Data by being easier to use, but it comes with a price of being a major third-party dependency.

Firebase is a different beast and it is very simple to prepare an MVP of your application using Firebase solutions instead of writing your own server. The customization is rather limited though.

There is no such thing as “the best database” because all of their pros and cons make them more or less suitable for different applications. It is up to developers to decide which database solution is the best for your specific needs. Here at Appus Studio we always analyze the project requirements before picking a mobile database solution to go with.

Discussion

markdown guide
 

Disappointed to not see Couchbase Lite in the list. We love it and it has amazing features for free. It does not require Couchbase server to be useful. It can stand alone all on its own. Encryption, Full Text Search, Full query engine. Its amazing.

 

Im using Realm in iOS and ObjectBox in Android.