Swift group Realm результаты запроса - PullRequest
0 голосов
/ 15 марта 2019

В моем приложении 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, имя: "Бар")

и несколько проектов,

Project (ID проекта: 100, менеджер:, сообщения: [a1, a2, a3], lastMessage:)

a1 = Задача (проект: <# 100>, идентификатор задачи: «a1», описание: «Задача 1 о проект 100 ", createDate: Date ())

a2 = Задача (проект: <# 100>, идентификатор задачи: «a2», описание: «Задача 2 о проект 100 ", createDate: Date ())

a3 = Задача (проект: <# 100>, идентификатор задачи: «a3», описание: «Задача 3 о проект 100 ", createDate: Date ())

Project (ID проекта: 101, менеджер:, сообщения: [a1, a2, a3], lastMessage:)

b1 = Задача (проект: <# 101>, идентификатор задачи: "b1", описание: "Задача 1 о Проект 101 ", createDate: Date ())

b2 = Задача (проект: <# 101>, идентификатор задачи: "b2", описание: "Задача 2 о проект 101 ", createDate: Date ())

b3 = Задача (проект: <# 101>, идентификатор задачи: «b3», описание: «Задача 3 о проект 101 ", createDate: Date ())

b4 = Задача (проект: <# 101>, идентификатор задачи: "b3", описание: "Задача 3 о проект 101 ", createDate: Date ())

Project (ID проекта: 102, менеджер:, сообщения: [a1, a2, a3], lastMessage:)

c1 = Задача (проект: <# 102>, идентификатор задачи: "c1", описание: "Задача 1 о Проект 102 ", createDate: Date ())

Project (ID проекта: 103, менеджер:, сообщения: [a1, a2, a3], lastMessage:)

d1 = Задача (проект: <# 103>, идентификатор задачи: "d1", описание: "Задача 1 о проект 103 ", createDate: Date ())

d2 = Задача (проект: <# 103>, идентификатор задачи: "d2", описание: "Задача 2 о проект 103 ", createDate: Date ())

d3 = Задача (проект: <# 103>, идентификатор задачи: "d3", описание: "Задача 3 о проект 103 ", createDate: Date ())

В моем ProjectsViewController

Я могу получить результаты своего царства как

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 -> [Проект 100, Массив задач], [Проект 102, Массив задач]

Бар -> [Проект 101, Массив задач], [Проект 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 голосов
/ 18 марта 2019

Я отвечу, основываясь на том, что я думаю вы спрашиваете.

Если я правильно понимаю, вы хотите найти словарь с Person в качестве ключа,значения представляют собой словарь с идентификатором проекта (или проектом) в качестве ключа и значения массива задач.т. е.

let result : [Person:[Project:[Task]]] = .....

Если это не правильно, вы, вероятно, можете взять идеи здесь и втиснуть их в свой идеал.

Если вы хотите, чтобы ключ от человека, я бы добавилОбратное свойство поиска к классу 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
}

Если вы хотите, чтобы задачи были отсортированы, то добавьте вычисляемое свойство к Projects с именем sortedTasks, которое делает это дляВы.

Как только это будет сделано, вы можете добавить куда-нибудь функцию (глобальную или статическую к 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
  }
}

Простите за любые ошибки компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...