Product College starts on September 18. Submit your application today. Apply now.

Local Storage with Realm

Local Storage with Realm

June 11, 2015

Project: Learn how to build Make School Notes!

We have taken the first steps of building a Notes app together. You can now create your own custom table view list and populate it with some basic test data.

In most apps, you will want a way to archive your user data. Having a list is great, but the user is going to be pretty unimpressed if your app loses all their precious notes after the app is restarted. That's a 1 Star review waiting to happen.


In this context, persistence is the ability to save data so that when you close an app and reopen it, the data is still there.

How to achieve persistence

  • Upon activation, load object state from persistent storage
  • Before deactivation, store object state to persistent storage

Hold up... This sounds like it could be painful...

Thankfully, this is an age old problem with many different solutions. Apple offers you Core Data as a complete framework for object graph management. It can be a great solution, but it is also a lot of work. :)

Let's look at a lightweight alternative called Realm.


What is Realm?

Realm is a replacement for SQLite & Core Data. It can save you thousands of lines of code & weeks of work, and lets you craft amazing new user experiences.

Hmmmmm... I like saving lines of code and I like saving work...

OK, I'm convinced. Let's take it for a spin. Time to implement Realm into our Note object. You can find this under the Entities group.

import Foundation
import RealmSwift

class Note : Object {

So we've dynamically imported the Realm library so we have access to this functionality.

Let's add the following variables to create our Note model class.

dynamic var title: String = ""
dynamic var content: String = ""
dynamic var modificationDate = NSDate()

Dynamic Attribute

What is all this Dynamic business? This attribute informs the Swift compiler that storage and implementation of a property will be provided at runtime.

You will be pleased to know that's all it takes to implement your Note data model. Nice!

Displaying Realm Object Data

Time to knuckle down. It's going to take a little bit of coding to switch over to Realm and add a test note in code.

Open NoteTableViewCell.swift and enter the following code:

class NoteTableViewCell: UITableViewCell {

    // initialize the date formatter only once, using a static computed property
    static var dateFormatter: NSDateFormatter = {
        var formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var dateLabel: UILabel!

    var note: Note? {
        didSet {
            if let note = note, titleLabel = titleLabel, dateLabel = dateLabel {
                titleLabel.text = note.title
                dateLabel.text = NoteTableViewCell.dateFormatter.stringFromDate(note.modificationDate)


Code Optimization

Wow, what is with static var dateFormatter? Glad you asked! This is a code optimization for a NSDateFormatter object. Some objects are notoriously slow to initialize, so you want to be able to reuse them instead of creating a new one every time. When I say 'slow' this is a relative term. With one object, you might not even notice the difference. However, if you are processing hundreds of objects, the initialization time adds up and if it only takes a few lines of code to optimize, then it's code that's worthwhile.

I wouldn't expect you at this stage to start worrying about optimizations. Focus on your application experience first. However, it's good to know there is always a little extra juice that can be squeezed out of an app. This comes with experience.


So you've added a variable to store the Note object, what is didSet? Well it's a rather handy bit of functionality that will be called whenever this note object is modified.

For example, if the note gets edited anywhere, this function will be called that will update the Outlet labels and therefore update the NoteCell in our list.

if - let

Remember back to Optionals and how sometimes a variable can be empty - represented by nil? If we forget about this and go about coding normally, our application is likely to crash and burn, not exactly a great experience for your users. If - let allows us to ensure that the variable does hold a value, and continue to code as usual.

if let thing1 = thing2 {...} says: assign the value (or nil) in thing2 to thing1, and afterwards if thing1 holds a non-nil value, execute the code within the following curly braces. This means that you can use thing1 within the block of code contained in the curly braces safely, without worrying about unexpected behavior due to a nil value.

In our example, we make sure that note, titleLabel, and dateLabel are properly set before we execute our code involving them.

Notes Collection

Before you create a new note, you need to add a notes variable to our NotesViewController so we can populate the table view.

Add the following code to the top of the NotesViewController class:

var notes: Results<Note>! {
    didSet {
        // Whenever notes update, update the table view

Since the Results type comes from the Realm framework, we will need to include the framework in the NotesViewController.swift file.

Add the following to the top of NotesViewController.swift:

import RealmSwift

Notice the use of didSet to refresh the tableView when Notes results are updated - very handy. Let's add some notes.

Creating A New Note

Our NoteCell can now display information from a Note object. Let's create one to see this in action.

Add the following to the end of your viewDidLoad function in NotesViewController.swift to initialize a new Note object.

let myNote = Note()
myNote.title   = "Super Simple Test Note"
myNote.content = "A long piece of content"

Great! You have a new note but nowhere to put it. Let's save it to our Realm local storage with a simple 3 step process.

Saving A Note

Add the following code right after the previous code.

  do {
      // 1
      let realm = try Realm()
      // 2
      try realm.write() {
        // 3

  } catch {
    print("handle error")

Note: The do, try, and catch keywords are all used for error handling. For now, do not worry about handling errors, we will discuss it in Makestagram

  1. Before you can add it to Realm you must first grab the default Realm.
  2. All changes to an object (addition, modification and deletion) must be done within a write transaction/closure.
  3. Add your new note to Realm

Realm makes this whole process nice and easy.

Loading All Notes

We now need to update our notes variable to contain all of the same data as our Realm database.

Change the realm code in the viewDidLoad method of the NotesViewController class to look as follows:

  do {
      let realm = try Realm()
      try realm.write() {
    // 1
    notes = realm.objects(Note)
  } catch {
    print("handle error")

Very close now.....

Update protocol functions

Now that we are using Realm we need to update our table view code.

Replace the following code in tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)

cell.titleLabel.text = "Hello"
cell.dateLabel.text = "Today"


let row = indexPath.row
let note = notes[row] as Note
cell.note = note

Now instead of putting in note titles and dates ourselves, we're going to allow the app to read that information from the notes stored in Realm.

Also replace the following code in func tableView(tableView: UITableView, numberOfRowsInSection section: Int)

return 5


return notes?.count ?? 0

So if notes isn't empty, numberOfRowsInSection will return notes.count; otherwise it will return 0.

In the above code, note how the operator ?? handles the case in which the variable notes is nil and empty.

It is equivalent to using an if statement.

if let notes = notes {
    return Int(notes.count)
} else {
    return 0

We would probably have other, bigger issues in our code if notes was ever nil, but it's still good to be a safe programmer. No one likes using apps that crash :)

Finally, it's time to run the app!

It should look a little like this:


The more times you run it, the more notes will be added.
If you wish to clear out the notes for testing, add the following into your realm write closure (from Saving A Note): realm.deleteAll()

As you have found out, Realm is a great lightweight framework to add data persistence to your app. You also explored how to add new notes in code. The app is starting to come together now.

In the next chapter we will be looking at the next steps to enable the capture of user input to create new notes.


If you have feedback on this tutorial or find any mistakes, please open issues on the GitHub Repository.

Summer academy

An iOS Development Summer Course

Design, code and launch your own app. Locations across the USA and Asia

Find your location

Product College

A computer science college

Graduate into a successful career as a founder or software engineer.

Learn more