2017-01-27 3 views
2

У меня есть два объекта Realm, называемые Chat и ChatMessage. Между ними существует взаимосвязь «один ко многим».Сортировка внутри подзапроса

class Chat: Object { 
    dynamic var id: String = "" 
    dynamic var createdAt: Date = Date() 
    dynamic var creatorId: String = "" 
    let chatMessages = List<ChatMessage>() 

    override static func primaryKey() -> String? { 
     return "id" 
    } 
} 

class ChatMessage: Object { 
    dynamic var id: String = "" 
    dynamic var chatId: String = "" 
    dynamic var createdAt: Date = Date() 
    dynamic var read: Bool = false 
    dynamic var authorId: String = "" 
    dynamic var text: String = "" 
    let chat = LinkingObjects(fromType: Chat.self, property: "chatMessages").first 

    override static func primaryKey() -> String? { 
     return "id" 
    } 
} 

Мне нужно отобразить список чатов, где чаты с последними сообщениями вверху. Как во всех чат-приложениях. Для этого я решил, что мне нужно отсортировать объекты Chat по значению свойства createdAt объектов ChatMessage, связанных с каждым чатом.

Это то, что у меня есть до сих пор.

func getChats() -> Results<Chat> { 
    let realm = try! Realm() 
    let chats = realm.objects(Chat.self) 
    let predicate = NSPredicate(format: "SUBQUERY(Chat, $chat, $chat.chatMessages)", argumentArray: nil) 
    return chats.filter(predicate) 
} 

Я не знаю, как сортировать chatMessages внутри подзапроса. Или, если это возможно. Искал Realm docs, но ничего не нашел. Любая помощь приветствуется. Или любые предложения, если есть лучший способ сделать это.

ответ

1

Запрос filter предназначен для изоляции конкретных объектов, а не для их фактической сортировки. Поэтому попытка сортировки в NSPredicate на самом деле не осуществима.

В настоящее время в Realm GitHub отслеживается проблема для allowing sorting via to-many child objects. Это в теории, в конечном счете, означает, что вы могли бы просто сделать:

let chats = realm.objects(Chat.self).sorted(byKeyPath: "chatMessages.createdAt")

Я определенно рекомендую вам добавить свой +1 к этому вопросу так что его приоритет может получить толкал вверх. :)

В то же время, хотя и не является абсолютно удивительным решением, можно добавить дополнительный Date свойство Chat, что просто lastUpdated, который копирует дату самого последнего ChatMessage объекта. Таким образом, вы можете отсортировать объекты Chat непосредственно с этим.

+0

Спасибо за ответ Тим. Да, я уже наткнулся на эту проблему Github и поддержал ее :) Думаю, я бы сделал предлагаемое решение. Кстати, есть ли способ в Realm сделать новое добавленное свойство 'Date' в' Чат' автоматически обновляться всякий раз, когда добавляется новый объект 'ChatMessage'? Или мне нужно установить его вручную? – Isuru

+0

@Isuru Мое удовольствие! Круто! Спасибо за это! Хм ... вы могли бы использовать систему уведомлений Realm, чтобы инициировать оповещение, когда свойство 'chatMessages' обновляется, но это может быть несколько громоздким. Вероятно, самым простым способом было бы добавить удобный метод для 'Chat' с именем' addMessage() ', который заботится о том, чтобы добавить новое сообщение в« Список », а также обновить свойство lastUpdated. :) – TiM

+0

Кажется, хорошая идея. Спасибо. – Isuru