自定义 NSFetchreqeust - 按子 NSSet 属性排序父实体 [MagicalRecord+Coredata]

Posted

技术标签:

【中文标题】自定义 NSFetchreqeust - 按子 NSSet 属性排序父实体 [MagicalRecord+Coredata]【英文标题】:Custom NSFetchreqeust - sort parent entities by child NSSet attributes [MagicalRecord+Coredata] 【发布时间】:2015-02-11 03:48:39 【问题描述】:

这是我的项目数据模型。

此处的数据模型适用于简单的 IM 应用。 1.用户对话(现阶段1对1) 2. 对话 消息(一对多)

我调用下面的代码来保存我从 web-socket 收到的消息,这是一个 JSON 字符串。我只是简单地将它们转换为 Coredata 实体。

    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) 

        ChatMessage* chatMessage = [ChatMessage MR_createInContext:localContext];

        NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
        [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
        [formatter setDateFormat:@"YYYY/MM/dd HH:mm:ss"];

        [chatMessage setCreateDate:[formatter dateFromString:[jsonData valueForKey:@"createDate"]]];
        [chatMessage setMessageBody:[jsonData valueForKey:@"textBody"]];
        [chatMessage setMessageID:[jsonData valueForKey:@"id"]];
        [chatMessage setSenderID:[jsonData valueForKey:@"senderID"]];

        if ( ! [[jsonData valueForKey:@"readDate"] isEqualToString:@"NULL"])
            [chatMessage setReadDate:[formatter dateFromString:[jsonData valueForKey:@"readDate"]]];
        else
            [chatMessage setReadDate:nil];


        if ([ChatConversation MR_findFirstByAttribute:@"user.userID" withValue:[jsonData valueForKey:@"senderID"]]) 

            ChatConversation* conversation = [ChatConversation MR_findFirstByAttribute:@"user.userID" withValue:[jsonData valueForKey:@"senderID"] inContext:localContext];

            [conversation addMessageObject:chatMessage];

        else
            ChatConversation* conversation = [ChatConversation MR_createInContext:localContext];
            [conversation setConversationID:[NSString stringWithFormat:@"%ld",[[ChatConversation MR_numberOfEntities] integerValue] +1]];
            [conversation addMessageObject:chatMessage];
            [conversation setUser:[ChatUser MR_findFirstByAttribute:@"userID" withValue:[jsonData valueForKey:@"senderID"] inContext:localContext]];
        

 completion:^(BOOL success, NSError *error) 
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
    [self displayMRRecord];
];

目前的挑战是这样的,我需要创建一个消息收件箱tableview。 像这样

“对话”按最后一条消息“createDate”排序。 所以我创建了一个 UITableViewController 来做到这一点。

这是我的 fetchedResultsController 初始化代码。

    _fetchedResultsController = [ChatConversation MR_fetchAllSortedBy:@"message.createDate" ascending:TRUE withPredicate:nil groupBy:nil delegate:self];

我意识到问题是,,,

    message是一个NSSet,一组实体,所以message.createDate不合适 我需要创建一个自定义 NSFetchRequest 并用它初始化 fetchedResultsController

所以我真正的问题是, 如何构造一个 NSFetchRequest,通过子实体集属性的最后一个对象(最新的 message.createDate)对父实体(在本例中为 ChatConversation)进行排序。

我用谷歌搜索了一整天,但找不到任何有用的资源。 有没有人有处理这种问题的经验? 谢谢

【问题讨论】:

【参考方案1】:

是的,我自己解决了。

   _fetchedResultsController = [ChatConversation MR_fetchAllSortedBy:@"message.createDate" ascending:TRUE withPredicate:nil groupBy:nil delegate:self];

此行以错误的方式调用。 我应该这样说。

    获取所有 ChatConversation 实体到 fetchResultsController.fetchedObject 数组

    _fetchedResultsController = [ChatConversation MR_fetchAllSortedBy:@"conversationID" ascending:TRUE withPredicate:nil groupBy:nil delegate:self];
    

    然后简单地使用自定义 NSSortDescripter 对 fetchedResultsController.fetchedObjects 数组进行排序

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"message[LAST].createDate" ascending:YES];
    
    NSArray *sortDescriptors1 = @[sortDescriptor];
    
    [_fetchedResultsController.fetchedObjects sortedArrayUsingDescriptors:sortDescriptors1];
    

【讨论】:

以上是关于自定义 NSFetchreqeust - 按子 NSSet 属性排序父实体 [MagicalRecord+Coredata]的主要内容,如果未能解决你的问题,请参考以下文章

按子数组值对数组进行分组

按子数组总和大小 Ruby 拆分子数组数组

按子文档 ID 查找并更新其数据

PHP Laravel 按子顺序排序

Firebase 按子值搜索

PHP:按子数组的出现次数对多维数组进行排序