Getting Started with Realm Database for iOS in Swift
In this tutorial we will learn the basics of Realm Database, from installing it to building the models and writing the create, read, update and delete methods.
If you are looking for an in depth Realm Database tutorial, then this is not the article for you. I am looking to write some more focussed articles on Realm in the future. Once I do, I will link to them here.
Step 1: Adding Realm Database to your project
There are a few ways to installing Realm, but in this tutorial we will be using CocoaPods.
If you do not have CocoaPods installed you can install it by going to the root directory of your project and running the following command, sudo gem install cocoapods
. I tried using the latest CocoaPods, which is 1.9.0
at the time of writing, but it did not work for me. If you run into the same issue you can use CocoaPods 1.6.0
. To install 1.6.0
you can use the following command, sudo gem install cocoapods -v 1.6.0
After doing that you need to run pod repo update
. This command will update CocoaPods so that is knows about the latest version of Realm.
Next you need to create a Podfile
. To do this create a new file called Podfile
in the root directory of your project. Add the following to your Podfile
:
use_frameworks!
pod 'RealmSwift'
After adding the above to my Podfile, it looks like this:
# Uncomment the next line to define a global platform for your project
platform :ios, '11.0'
target 'GettingStartedWithRealm' do
use_frameworks!
pod 'RealmSwift'
end
I updated my platform
to iOS 11.
Once you have created your Podfile
and added the code from above you need to run pod install
in your root directory. By doing this CocoaPods will install Realm into your project.
Once it is installed you need to close your project if you have opened it with Xcode. CocoaPods
requires us to use the xcworkspace
file when opening the project and not the xcodeproj
file.
Step 2: Import RealmSwift
I am going to be using the default ViewController
file for this entire tutorial. If this was a real project I would split it up into different parts.
To import Realm into the ViewController, all we need to do is add the following import:
import RealmSwift
Step 3: Create the Models
When we are creating a model we need that model to be a subclass of Object
. In this tutorial we will be creating a furniture store, so our two models will be Furniture
and Store
.
To create those two models, add the following to the ViewController
file:
class Furniture: Object {
@objc dynamic var name = ""
static func create(withName name: String) -> Furniture {
let furniture = Furniture()
furniture.name = name
return furniture
}
}
class Store: Object {
@objc dynamic var name = ""
var furniture = List<Furniture>()
static func create(withName name: String,
furniture: [Furniture]) -> Store {
let store = Store()
store.name = name
store.furniture.append(objectsIn: furniture)
return store
}
}
The Furniture
class has one property, name
, and our Store
class has two properties, the store name
and a list of its furniture
. Both models also have a create
method which will allow us to create a new instance.
Step 4: Write to Realm
Now that we have our models setup, we can start saving data to our database. To write, we are going to create a simple method that will write data to our database. This write method will not take any parameters as it is for tutorial purposes.
Add the following method to your ViewController
:
private func write() {
let table = Furniture.create(withName: "table")
let chair = Furniture.create(withName: "chair")
let store = Store.create(withName: "Test Store",
furniture: [table, chair])
// Write to Realm
print("Write to Realm")
try! realm.write {
realm.add(table)
realm.add(chair)
realm.add(store)
}
}
The above write
function creates two Furniture
instances, one being table
and one being chair
, we also created one instance of Store
. When creating the table
and chair
we just provide it with a name, for the store
we provide it with a name and we pass through the table and chair that we just created.
When we create these instances they are only in memory and have not been written to our database. To write it to our database we need to wrap the add
method with try! realm.write
as shown in the above code.
In Step 8 we will call all the methods that we are going to create. If we call it now it will save the above data every time the app runs.
Please note: In this tutorial we are force unwrapping try!
, this means that if there is an error the app will crash. Please use the appropriate methods to safely do this in a production app.
Step 5: Read from Realm
We have our write
method created. Which will allow us to write data to our database, now we need to read the data from the database. Once again, as with all these methods, they are just created for tutorial purposes. If one was going to write this for production we would want to be able to choose what to read, write, update and delete from the database.
But for now, let's create the read
method. Add the following code below the write
method:
private func read() {
// Read from Realm
print("Read from Realm")
let data = realm.objects(Store.self)
print(data)
}
All the above method will do is fetch the objects that we tell it to fetch. In the above code we pass through Store.self
which will tell realm to fetch all the stores that we have saved.
At the moment we have not saved anything. But we will be saving stuff later on. For now, we can move on to updating data.
Step 6: Update existing data
In this update
method we are going to read the first item of furniture in the database and we will update the name of it.
In our case, the first item of furniture will be the table because that is what we saved first in the write
method. We have not called the write
method yet, but we will call it in Step 8.
For now, we can add the update
method below the read
method:
private func update() {
// Update data
if let table = realm.objects(Furniture.self).first {
try! realm.write {
table.name = "New Table Name"
}
print(realm.objects(Furniture.self).first)
}
}
The above code is a combination of our read
and write
methods.
In the code above we try and get the first Furniture
item. It it exists, we will write it to realm by updating the property value inside try! realm.write
.
After the value is saved, we will print out the first item of furniture. This will have the updated name.
Please note: In this tutorial we are force unwrapping try!
, this means that if there is an error the app will crash. Please use the appropriate methods to safely do this in a production app.
Step 7: Delete data
The delete
method is very similar to the update
method.
Add the following code below the update method:
private func delete() {
// Delete data
print("Delete Data")
if let tableToDelete = realm.objects(Furniture.self).first {
try! realm.write {
realm.delete(tableToDelete)
}
print(realm.objects(Furniture.self).first)
print(realm.objects(Store.self).first)
}
}
As with the update
method, we will get the first furniture item that we have saved. If it exists, we will delete it. Realm has a delete method built in. To use the delete method we need to wrap it in try! realm.write
as we would normally do when writing to the database or when updating the database.
After we have deleted the furniture item, we print out all the furniture items that are in the database and we print out the store. The store will now only have one furniture item.
Please note: In this tutorial we are force unwrapping try!
, this means that if there is an error the app will crash. Please use the appropriate methods to safely do this in a production app.
Step 8: Calling the methods
Now that all of our methods have been created, we can call them. I have called all these methods from the viewDidLoad
method. Update your viewDidLoad
method to look like the following:
override func viewDidLoad() {
super.viewDidLoad()
self.write()
self.read()
self.update()
self.read()
self.delete()
}
If you build and run the app now, you will get something similar to the below output in Xcode
console:
Write to Realm
Read from Realm
Results<Store> <0x7fb63275d8d0> (
[0] Store {
name = Test Store;
furniture = List<Furniture> <0x600003f19560> (
[0] Furniture {
name = table;
},
[1] Furniture {
name = chair;
}
);
}
)
Optional(Furniture {
name = New Table Name;
})
Read from Realm
Results<Store> <0x7fb63260b3e0> (
[0] Store {
name = Test Store;
furniture = List<Furniture> <0x600003f1e250> (
[0] Furniture {
name = New Table Name;
},
[1] Furniture {
name = chair;
}
);
}
)
Delete Data
Optional(Furniture {
name = chair;
})
Optional(Store {
name = Test Store;
furniture = List<Furniture> <0x600003f15b90> (
[0] Furniture {
name = chair;
}
);
})
This is the output from all the print statements that we added to the code. As you can see, we write the data. Once the data has been written, we will read the data. This will show us what is in our Store
. As you can see, we have one Store
that has two items of furniture.
Next we call update. The update method will update the name of the table
furniture item. After we call update, we call read again to see the changes that have been made. When we call read it will print out our store again and we will see that the table that used be in the database now has the name New Table Name
.
After the update we call delete. We deleted the first item of furniture, so we are expecting to only see the chair
. As expected, when the delete method prints out all the furniture, all that is left is the chair
.
We also see that when the delete
method prints out the store, only the chair exists. So the store only contains 1 furniture item instead of 2.
Conclusion
And that is it! Realm is extremely easy to start with but the bigger question is should you use it? Would it be better than using Core Data? In most cases I personally prefer the tools that are created by Apple, but if Realm suits your use case best, then it would make sense to use it.
You can find the full source code here.