Adapting Apple's Scrumdinger SwiftUI Tutorial App to Use Realm
Rate this code example
Apple published a great to teach developers how to create iOS apps using SwiftUI. I particularly like it because it doesn't make any assumptions about existing UIKit experience, making it ideal for developers new to iOS. That tutorial is built around an app named "Scrumdinger," which is designed to facilitate daily meetings.
Apple's Scrumdinger implementation saves the app data to a local file whenever the user minimizes the app, and loads it again when they open the app. It seemed an interesting exercise to modify Scrumdinger to use Realm rather than a flat file to persist the data. This article steps through what changes were required to rebase Scrumdinger onto Realm.
An immediate benefit of the move is that changes are now persisted immediately, so nothing is lost if the device or app crashes. It's beyond the scope of this article, but now that the app data is stored in Realm, it would be straightforward to add enhancements such as:
This article was updated in July 2021 to replace
@Persistedannotation that was introduced in Realm-Cocoa 10.10.0.
- Mac (sorry Windows and Linux users).
- Xcode 12.4+.
From Xcode, select a simulator:
Build and run the app with
Create a new daily scrum. Force close and restart the app with
⌘r. Note that your new scrum has been lost 😢. Don't worry, that's automatically fixed once we've migrated to Realm.
https://github.com/realm/realm-cocoaas the package repository URL:
RealmSwiftpackage to the
We can then start using the Realm SDK with
To store an object in Realm, its class must inherit from Realm's
Objectclass. If the class contains sub-classes, those classes must conform to Realm's
As with the original app's flat file, Realm can't natively persist the SwiftUI
Colorclass, and so colors need to be stored as components. To that end, we need a
Componentsclass. It conforms to
EmbeddedObjectso that it can be embedded in a higher-level Realm
Objectclass. Fields are flagged with the
@Persistedannotation to indicate that they should be persisted in Realm:
DailyScrumis converted from a
classso that it can be persisted in Realm. By conforming to
ObjectKeyIdentifiable, lists of
DailyScrumobjects can be used within SwiftUI
ForEachviews, with Realm managing the
ididentifier for each instance.
We use the Realm
Listclass to store arrays.
Historystruct is replaced with a Realm
ObservableObjectclass was used to manage the copying of scrum data between the in-memory copy and a local iOS file (including serialization and deserialization). This is now handled automatically by Realm, and so this class can be deleted.
Nothing feels better than deleting boiler-plate code!
Once the data is being stored in Realm, there's no need for lifecycle code to load data when the app starts or save it when it's minimized, and so
ScrumdingerAppbecomes a simple wrapper for the top-level view (
The move from a file to Realm simplifies the top-level view.
DailyScrumobjects are automatically loaded from the default Realm using the
New scrums can be added to Realm by appending them to the
scrumsresult set with
$scrums.append(newScrum). Note that there's no need to open a Realm transaction explicitly. That's now handled under the covers by the Realm SDK.
MeetingViewis enhanced so that meeting notes are added as soon as they've been created (rather than being stored in volatile RAM until the app is minimized):
There are no changes needed to the view that's responsible for displaying a summary for a scrum. The changes we made to the
DailyScrummodel in order to store it in Realm don't impact how it's used within the app.
Similarly, there are no significant changes needed to
I hope that this post has shown that moving an iOS app to Realm is a straightforward process. The Realm SDK abstracts away the complexity of serialization and persisting data to disk. This is especially true when developing with SwiftUI.