我想通过一些谓词来限制领域结果中的对象,以便观察该结果并根据其更改来更新UI。
我已经看到了几种解决方案,它们争辩说,因为领域中的对象是延迟加载的,因此不需要限制查询。但是,我希望查询按限制限制结果,以便在受到限制限制的对象发生更改时触发更改通知。
让我给你举个例子:
假设我有一个包对象:
class Package: Object {
@objc enum State: Int {
case scheduled
case delivered
}
@objc dynamic var state = State.scheduled
@objc dynamic var deliveryDate = Date()
}
,我想创建所有已计划的程序包的结果,并且仅提供已交付的最新程序包。我将如何去做?甚至只有一个结果我就可以观察到变化吗?
更新:
尝试更加清楚我要寻找的内容。可以说我的领域中包含以下软件包:
Package1
state: delivered
deliveryDate: March 1st
Package2
state: delivered
deliveryDate: March 2nd
Package3
state: delivered
deliveryDate: March 3rd
Package4
state: scheduled
deliveryDate: March 4th
Package5
state: scheduled
deliveryDate: March 5th
Package6
state: scheduled
deliveryDate: March 6th
,假设这些软件包每天都会更改状态。因此,在3月3日,数据将看起来如上,但是在3月4日,Package4会将状态更改为“已交付”。然后,我希望得到能在这两天反映以下内容的结果:
March 3rd:
- Package3 (delivered)
- Package4 (scheduled)
- Package5 (scheduled)
- Package6 (scheduled)
March 4th:
- Package4 (delivered)
- Package5 (scheduled)
- Package6 (scheduled)
答案 0 :(得分:1)
我要尝试答案,但是可能不正确。
目标是拥有一个单一的领域结果,可以观察到变化并知道最新的交付结果。
这是代码
self.packageResults = realm.objects(Package.self).sorted(byKeyPath: "delivered", ascending: false)
然后观察self.packageResults。
只要有更改,observation闭包就会触发并传递结果,并以降序排列,因此最新传递将位于“顶部”,即索引0。
编辑
根据评论并对该问题进行更新,有一个问题是该答案是否可以提供解决方案。现在有更多数据,只需稍作修改即可产生所需的结果(几乎保持读取状态)
self.packageResults = realm.objects(Package.self)
.filter("deliveryDate => 20190303")
.sorted(byKeyPath: "state", ascending: false)
然后将观察者添加到self.packageResults中。 (请注意,我将Int用于时间戳记以使其保持简单)
为了进行测试,我们将问题中提供的数据与观察者代码一起使用。该代码将打印数据的初始状态,然后在进行任何删除,插入或修改后打印状态。
func doObserve() {
self.notificationToken = self.packageResults!.observe { (changes: RealmCollectionChange) in
switch changes {
case .initial:
print("initial load complete")
if let results = self.packageResults {
for p in results {
print(p.deliveryDate, p.state.rawValue)
}
}
break
case .update(_, let deletions, let insertions, let modifications):
if let results = self.packageResults {
for p in results {
print(p.deliveryDate, p.state.rawValue)
}
}
然后我们运行代码并添加观察者。这是输出
initial load complete
20190303 1
20190304 0
20190305 0
20190306 0
如果我们随后将包20190304更改为“已交付”,则会得到以下输出
20190303 1
20190304 1
20190305 0
20190306 0
所以我们得到了预期的结果。但是,根据该问题,查询条件发生了变化,因为下一个查询将针对日期20190304及之后。
如果输出条件改变,则查询条件也必须改变。在这种情况下,理想的结果是每天显示最近交付的包裹,因此查询需要每天进行更新以反映该日期。
作为一种可能的解决方案,更改Package对象以包括受监视的属性
class Package: Object {
@objc enum State: Int {
case scheduled
case delivered
}
@objc dynamic var state = State.scheduled
@objc dynamic var deliveryDate = 0
@objc dynamic var watched = false
}
并更新查询以仅观察正在监视的软件包,忽略不监视的软件包(其中watched = false)
self.packageResults = realm.objects(Package.self)
.filter("deliveryDate => 20190303 and watched == true")
.sorted(byKeyPath: "state", ascending: false)
然后,当您不再需要了解某个对象时,请将其watched属性设置为false,它将不包括在结果中。使用与上述查询相同的过程,将20190304更改为交付时,我们还将20190303 watched属性更改为false,结果是
handle item delete, insert or mod
20190304 1
20190305 0
20190306 0
似乎可以回答问题。