gpt4 book ai didi

ios - 如何使用 Realm 通知来检测嵌套 Realm 对象的更改

转载 作者:行者123 更新时间:2023-11-29 05:29:39 24 4
gpt4 key购买 nike

我正在尝试为ios构建一个应用程序来显示各种节日日常节目。在此应用程序中,我希望每次“添加”、“修改”或“删除”组成节日节目的事件之一时都会通知用户。

对于数据库,我正在使用 Realm 云服务。我的数据库的结构如下:我有一个名为“Festival”的 Realm 对象。在其中我有一个“DailyProgram”对象列表,在每个“DailyProgram”内部我有一个“Event”列表。我在下面提供了这些对象的片段。

当应用程序访问 Realm Cloud 时,它会下载一个包含所有不同节日的数组。
我想使用 Realm 内置通知系统来检测“事件”对象中的更改。

我尝试在此节日数组上实现集合通知,但是当我在数据库中对一个事件进行更改时,集合通知仅返回与发生更改的节日相对应的数组索引。我想获取有关发生更改的特定事件以及更改内容的信息。

class Festival: Object {

@objc dynamic var festivalId: String = UUID().uuidString
@objc dynamic var name: String = ""
@objc dynamic var town: String = ""
@objc dynamic var initialDate: Date = Date()
@objc dynamic var finalDate: Date = Date()

let program = List<DailyProgram>()

override static func primaryKey() -> String? {
return "festivalId"
}
}
class DailyProgram: Object{

@objc dynamic var day: Date = Date()
let events = List<Event>()
}
class Event: Object {
@objc dynamic var name: String = ""
@objc dynamic var local: String = ""
@objc dynamic var time: Date = Date()

}

我很清楚 Realm 中对象通知的存在。我认为这些可能是我的问题的解决方案。我知道如何在单个对象上实现对象通知。但是,我不知道如何在嵌套对象的情况下实现这些类型的通知。

最佳答案

简短的回答:

在事件和它所属的节日之间创建逆关系。然后根据属于特定节日的事件获取结果并观察它们。然后,当该节日添加、修改或删除任何事件时,您都会收到通知。

基于长代码的答案。从修改 Realm 对象开始(我删除了属性以缩短代码)

class Festival: Object {
@objc dynamic var festivalId: String = UUID().uuidString
@objc dynamic var name: String = ""
let program = List<DailyProgram>()
override static func primaryKey() -> String? {
return "festivalId"
}
}

class DailyProgram: Object {
@objc dynamic var day = ""
@objc dynamic var festival: Festival! //add this
let events = List<Event>()
}

class Event: Object {
@objc dynamic var daily_program: DailyProgram!
@objc dynamic var festival: Festival! //add this
@objc dynamic var name: String = ""
}

然后创建对象,确保添加逆关系。请注意 var 命名,f0 = Fest 0,f1 = Fest 1,然后 dp = DailyProgram 和 e = Event。这样做是为了更容易看到层次结构。

let f0 = Festival()
f0.name = "Fest 0"

let f0dp0 = DailyProgram()
f0dp0.day = "Monday"
f0dp0.festival = f0

let f0dp0e0 = Event()
f0dp0e0.name = "Morning event"
f0dp0e0.daily_program = f0dp0
f0dp0e0.festival = f0

let f0dp0e1 = Event()
f0dp0e1.name = "Afternoon event"
f0dp0e1.daily_program = f0dp0
f0dp0e1.festival = f0


let f1 = Festival()
f1.name = "Fest 1"

let f1dp0 = DailyProgram()
f1dp0.day = "Monday"
f1dp0.festival = f1

let f1dp0e0 = Event()
f1dp0e0.name = "Evening event"
f1dp0e0.daily_program = f1dp0
f1dp0e0.festival = f1

let f1dp0e1 = Event()
f1dp0e1.name = "Midnight event"
f1dp0e1.daily_program = f1dp0
f1dp0e1.festival = f1

上面创建了两个节日,每个节日都有一个周一的每日节目,然后每个周一的节目有两个事件。

然后我们加载结果并添加观察者。在本例中,我们对 Fest 1 事件感兴趣。

var eventResults: Results<Event>? = nil
var eventNotificationToken: NotificationToken? = nil

func loadAndObserveFestivalEvents() {
if let realm = gGetRealm() {
self.eventResults = realm.objects(Event.self).filter("festival.name == %@", "Fest 1")
self.observeEvents()
}
}

func observeEvents() {
self.eventNotificationToken = self.eventResults!.observe { (changes: RealmCollectionChange) in
switch changes {
case .initial:
print("initial event load complete")
if let results = self.eventResults { //just shows events are loaded
for e in results {
let d = e.daily_program.day
let f = e.festival.name
print(f, d, e.name)
}
}
break
case .update(_, let deletions, let insertions, let modifications):
print(" handle event delete, insert or mod")
if let results = self.eventResults { //shows the list including the newly added event
for e in results {
let d = e.daily_program.day
let f = e.festival.name
print(f, d, e.name)
}
}
break
case .error(let error):
fatalError("\(error)")
break

}
}
}

此时,我们已准备好将一个事件添加到 Fest 1 的星期一事件中,然后收到该事件已添加的通知。

func addEvent() {
if let realm = gGetRealm() {
let dp = realm.objects(DailyProgram.self).filter("festival.name == %@ && day == %@", "Fest 1", "Monday")
if let daily = dp.first {
let eventToAdd = Event()
eventToAdd.daily_program = daily
eventToAdd.festival = daily.festival
eventToAdd.name = "Super Duper Event"

try! realm.write {
daily.events.append(eventToAdd)
}
}
}
}

代码的最后一部分创建一个结果对象,该对象填充有 Fest 1(星期一)的 DailyProgram。

然后,我创建一个新事件,确保将其链接回 Fest 1 节日,然后将其添加到 DailyPrograms 事件列表中。

这段代码可以大大缩短,并且可以利用 LinkingObject 自动创建反向链接。然而,在这种情况下,一项事件将只属于一个 DailyProgram 和 Festival,因此实际上并不需要。

注意gGetRealm是我用来连接到 Realm 的单例。

关于ios - 如何使用 Realm 通知来检测嵌套 Realm 对象的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57779619/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com