Swift Group Realm查询结果

时间:2019-03-15 12:12:05

标签: swift realm

我在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 
-------------------

1 个答案:

答案 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
  }
}

原谅任何编译错误。