我有以下型号
class Process: Object {
@objc dynamic var processID:Int = 1
let steps = List<Step>()
}
class Step: Object {
@objc private dynamic var stepCode: Int = 0
@objc dynamic var stepDateUTC: Date? = nil
var stepType: ProcessStepType {
get {
return ProcessStepType(rawValue: stepCode) ?? .created
}
set {
stepCode = newValue.rawValue
}
}
}
enum ProcessStepType: Int { // to review - real value
case created = 0
case scheduled = 1
case processing = 2
case paused = 3
case finished = 4
}
一个进程可以开始,处理,暂停,恢复(要再次在步骤中进行处理),暂停,再次恢复等。当前步骤是最新stepDateUTC
我正在尝试获取所有流程,最后一步是stepType处理“处理”的步骤,即。最后一个stepDate的stepCode是2。我附带以下谓词...这不起作用。对执行这种查询的权利有任何想法吗?
我最好的审判是那个。是否可以通过一个领域查询获得此结果。
let processes = realm.objects(Process.self).filter(NSPredicate(format: "ANY steps.stepCode = 2 AND NOT (ANY steps.stepCode = 4)")
let ongoingprocesses = processes.filter(){$0.steps.sorted(byKeyPath: "stepDateUTC", ascending: false).first!.stepType == .processing}
我希望能行得通
NSPredicate(format: "steps[LAST].stepCode = \(TicketStepType.processing.rawValue)")
我了解[LAST]不受领域支持(根据备忘单)。但是反正我可以通过领域查询实现目标吗?
有几种方法可以解决此问题,并且日期属性似乎不相关,因为列表是按顺序存储的(只要它们没有被更改),所以列表中的最后一个元素是最后添加的。] >
这第一段代码将过滤最后一个元素为'processing'的过程。我对此进行了长期编码,因此流程更易于理解。
let results = realm.objects(Process.self).filter { p in let lastIndex = p.steps.count - 1 let step = p.steps[lastIndex] let type = step.stepType if type == .processing { return true } return false }
请注意,Realm对象是延迟加载的-这意味着成千上万的对象对内存的影响很小。通过使用Swift进行过滤,对象将在内存中进行过滤,因此影响更为显着。
我建议使用第二段代码,因为它使过滤变得更加简单,但是需要对Process模型进行一些更改。
class Process: Object { @objc dynamic var processID:Int = 1 let stepHistory = List<Step>() //RENAMED: the history of the steps @objc dynamic var name = "" //ADDED: new property tracks current step @objc dynamic var current_step = ProcessStepType.created.index }
我在这里的想法是,流程模型保留了迄今为止已发生步骤的“历史记录”,以及当前步骤的内容。
我还修改了ProcessStepType枚举,使其更易于过滤。
enum ProcessStepType: Int { // to review - real value case created = 0 case scheduled = 1 case processing = 2 case paused = 3 case finished = 4 //this is used when filtering var index: Int { switch self { case .created: return 0 case .scheduled: return 1 case .processing: return 2 case .paused: return 3 case .finished: return 4 } } }
然后返回列表中最后一步是“处理中”的所有进程,这里是过滤器
let results2 = realm.objects(Process.self).filter("current_step == %@", ProcessStepType.processing.index)
最终的想法是向Process模型添加一些代码,因此,当将步骤添加到列表中时,current_step var也将被更新。保留给OP的编码。