我在Swift应用程序中关注了Realm对象(为简洁起见删除了init和其他非必需属性)
@objcMembers
class Person: Object {
dynamic var id: String = ""
dynamic var name: String = ""
override static func primaryKey() -> String? {
return "id"
}
}
@objcMembers
class Project: Object {
dynamic var projectId: Int = 0
dynamic var manager: Person?
var tasks = List<Task>()
dynamic var lastTask: Task?
override static func primaryKey() -> String? {
return "projectId"
}
}
@objcMembers
class Task : Object {
dynamic var project = LinkingObjects(fromType: Project.self, property: "tasks")
dynamic var taskId: String = ""
dynamic var description: String = ""
dynamic var createDate: Date = Date()
override static func primaryKey() -> String? {
return "taskId"
}
}
所以如果有2个项目成员
人员(ID:1,名称:“ Foo”)
人员(id:2,名称:“ Bar”)
和多个项目
Project(projectId:100,manager:,消息:[a1,a2,a3], lastMessage:)
a1 =任务(项目:<#100>,taskId:“ a1”,说明:“任务1关于 项目100”,createDate:Date())
a2 = Task(项目:<#100>,taskId:“ a2”,描述:“任务2关于 项目100”,createDate:Date())
a3 = Task(项目:<#100>,taskId:“ a3”,说明:“任务3关于 项目100”,createDate:Date())
Project(projectId:101,manager:,消息:[a1,a2,a3], lastMessage:)
b1 =任务(项目:<#101>,taskId:“ b1”,描述:“任务1关于 项目101”,createDate:Date())
b2 =任务(项目:<#101>,taskId:“ b2”,描述:“任务2关于 项目101”,createDate:Date())
b3 = Task(项目:<#101>,taskId:“ b3”,说明:“任务3关于 项目101”,createDate:Date())
b4 = Task(项目:<#101>,taskId:“ b3”,说明:“任务3关于 项目101”,createDate:Date())
Project(projectId:102,manager:,消息:[a1,a2,a3], lastMessage:)
c1 =任务(项目:<#102>,taskId:“ c1”,描述:“任务1关于 项目102”,createDate:Date())
Project(projectId:103,manager:,消息:[a1,a2,a3], lastMessage:)
d1 =任务(项目:<#103>,taskId:“ d1”,描述:“任务1关于 项目103”,createDate:Date())
d2 = Task(项目:<#103>,taskId:“ d2”,描述:“任务2关于 项目103”,createDate:Date())
d3 = Task(项目:<#103>,taskId:“ d3”,描述:“任务3关于 项目103”,createDate:Date())
在我的ProjectsViewController中
我可以得到我的Realm结果
func getProjects() -> Results<Project> {
let results: Results<Conversation> = database
.objects(Conversation.self)
.sorted(byKeyPath: "lastTask.createDate", ascending: false)
return results
}
[注意-如果有更好的方法根据任务列表的最后一项对结果进行排序,请告诉我。这将使lastTask var的使用变得多余。]
在我的表格视图中显示为
===================
Projects
-------------------
Foo
Project 100
Task a3
-------------------
Bar
Project 101
Task b4
-------------------
Foo
Project 102
Task c1
-------------------
Bar
Project 103
Task d3
-------------------
问题:如何在Realm查询中对结果进行分组,以便获得结果数组的字典,例如
Foo-> [Project 100,任务数组],[Project 102,任务数组]
Bar-> [Project 101,任务数组],[Project 103,任务数组]
,并且通过NotificationToken对所有插入/更新进行跟踪。另外,我想按表格视图中的各个部分对它们进行布局。
===================
Projects (Grouped)
-------------------
Foo (Section Header)
-------------------
Project 100
Task a3
-------------------
Project 102
Task c1
-------------------
-------------------
Bar (Section Header)
-------------------
Project 101
Task b4
-------------------
Project 103
Task d3
-------------------
答案 0 :(得分:0)
我会根据您的询问 来回答。
如果我的理解正确,您想找到一个以Person
为键的字典,值是一个以Project ID(或Project)为键的字典,以及一个任务数组的值。即
let result : [Person:[Project:[Task]]] = .....
如果这是不正确的,您可以在这里接受这些想法,然后将它们按摩成您的理想状态。
当您想按Person键输入时,我将向Person
类添加一个反向查找属性-这可能是您缺少的主要内容。请查看手册的本部分以获取指导:(https://realm.io/docs/swift/latest/#inverse-relationships),然后将此属性添加到Person
:
let projects = LinkingObjects(fromType: Project.self, property: "manager")
然后,我将计算属性添加到Person
中以检索项目和任务。这创建了一个数组,因为在问题中要求这样做。
var projectsAndTasks : [Project:[Task]]
{
var result : [Project:[Task]] = [:]
for project in projects
{
result[project] = project.tasks.map { $0 }
}
return result
}
如果您希望对任务进行排序,则将一个计算属性(称为sortedTasks)添加到Projects
中。
完成后,您可以在某个位置添加一个函数(Person
可以是全局的也可以是静态的)以将Person
的所有对象的结果添加到单个字典中。例如。 :
extension Realm
{
var allPersonsAndProjects : [Person:[Project:[Task]]]
{
var result : [Person:[Project:[Task]]] = []
let persons = objects(Person.self)
for person in persons
{
result[person] = person.projectsAndTasks
}
return result
}
}
原谅任何编译错误。