I have been using Realm in an app and love it. Thank you! I have a question I would like to run by you folks and get some advice.
Lets say you have a realm object that contains a date field (simplified example):
class Appointment: Object {
dynamic var type = ""
dynamic var date = Date()
}
Now, suppose you have saved thousands of Appointments, and you are going to display these on a tableview or collectionview, grouped by week for example. So the datasource for your view would be something like this.
struct AppointmentsInWeek {
var startDate: Date?
var endDate: Date?
var appointments: [Appointment]
}
So, I have two options in mind I am thinking through with various pros and cons:
A) Make AppointmentsInWeek
a subclass of Object
, save it in the Realm, and use that as the datasource.
Appointment
in Realm and as any are added put them in the appropriate AppointmentWeek
B) Upon loading the screen with the tableview, fetch all appointments, or a subset of them, group them by their appropriate start and end date, and create an AppointmentsInWeek
struct to use as the datasource.
AppointmentsInWeek
will always be up to date because it is created on the fly as neededI started with option B but I am thinking now it might be better to go with option A. If I do, the biggest issue is making sure the Realm is always up to date when new appointments are added.
Appointments
in Realm and when one is added (or changed), add it also to the appropriate AppointmentWeek
?Both options are fine, but I suggest option A. There are a few ways to approach option A.
First of all, you don't need to keep Appointment
and AppointmentsInWeek
in sync manually. You can use some combination of object properties, list properties, and linking objects properties to model connections between Appointment
s and AppointmentsInWeek
s. Exactly how you might implement this depends on your app's specific needs, but here's one possibility:
class Appointment : Object {
dynamic var type = ""
dynamic var date = NSDate()
// Link to the week this appointment lives in, if desired
var week: AppointmentsInWeek? = nil
}
class AppointmentsInWeek : Object {
dynamic var startDate = NSDate()
dynamic var endDate = NSDate()
// Add appointment to List whenever it's created
let appointments = List<Appointment>()
}
A second possibility is to not use relationships at all, but to use queries instead. Realm supports queries through the Results
class. You could add an ignored property on your AppointmentsInWeek
class that queries the Realm for all appointments that fall within its date range:
class Appointment : Object {
dynamic var type = ""
dynamic var date = NSDate()
}
class AppointmentsInWeek : Object {
dynamic var startDate = NSDate()
dynamic var endDate = NSDate()
lazy var appointments: Results<Appointment> = {
// This implementation assumes you can get a reference
// to the Realm storing your Appointments somehow
return appointmentsRealm.objects(Appointments.self).filter(NSPredicate(format: "(date >= %@) AND (date < %@)", self.startDate, self.endDate))
}()
override static func ignoredProperties() -> [String] {
return ["appointments"]
}
}
In either case Realms, lists, and results all update automatically whenever the runloop of the thread they are on (usually the main thread) runs. Realm also supports a variety of notifications in case you need to react to changes manually.