MagicalRecord NSFetchesResultsController 部分分组和排序 + 部分内也是如此

Posted

技术标签:

【中文标题】MagicalRecord NSFetchesResultsController 部分分组和排序 + 部分内也是如此【英文标题】:MagicalRecord NSFetchesResultsController section grouping and sorting + within section as well 【发布时间】:2013-01-22 14:59:31 【问题描述】:

我正在使用MagicalRecord 为表格创建NSFetchedResultsController

我有 NSManagedObjects 包含人群,这里有两个例子:

ContactGroup *everyoneContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPID>"];
if (!everyoneContactGroup) 
    everyoneContactGroup = [ContactGroup createEntity];
    [everyoneContactGroup setGroupId:@"<GROUPID>"];
    [everyoneContactGroup setGroupName:@"Everyone"];
    [everyoneContactGroup setGroupSortOrder:@1]; // sort order within section
    [everyoneContactGroup setGroupType:@1];
    [everyoneContactGroup setGroupTypeName:@"Smart Groups"];
    [everyoneContactGroup setGroupTypeSortOrder:@0]; // sort order for groups


ContactGroup *closeFriendsContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPIDCLOSEFRIENDS>"];
if (!closeFriendsContactGroup) 
    closeFriendsContactGroup = [ContactGroup createEntity];
    [closeFriendsContactGroup setGroupId:@"<GROUPIDCLOSEFRIENDS>"];
    [closeFriendsContactGroup setGroupName:@"Close Friends"];
    [closeFriendsContactGroup setGroupSortOrder:@2];
    [closeFriendsContactGroup setGroupType:@2];
    [closeFriendsContactGroup setGroupTypeName:@"Custom Groups"];
    [closeFriendsContactGroup setGroupTypeSortOrder:@10];


ContactGroup *familyContactGroup = [ContactGroup findFirstByAttribute:@"groupId" withValue:@"<GROUPIDFAMILY>"];
if (!familyContactGroup) 
    familyContactGroup = [ContactGroup createEntity];
    [familyContactGroup setGroupId:@"<GROUPIDFAMILY>"];
    [familyContactGroup setGroupName:@"Family"];
    [familyContactGroup setGroupSortOrder:@1];
    [familyContactGroup setGroupType:@2];
    [familyContactGroup setGroupTypeName:@"Custom Groups"];
    [familyContactGroup setGroupTypeSortOrder:@10];

上面应该显示如下:

如您所见,联系人组“Everyone”应该被分组到它自己的一个部分中,并且应该按组的顺序显示为第一个组。

上面的第二个和第三个联系人组应该一起组成一个部分,这个部分应该出现在另一个部分的下方,其中有一个组。在此组(“自定义组”)内,每个联系人组都应按其groupSortOrder 排序。

这是我的 NSFetchedResultsController 代码:

- (NSFetchedResultsController *)fetchedResultsController 
    if (!fetchedResultsController) 
        fetchedResultsController = [ContactGroup fetchAllSortedBy:@"groupTypeSortOrder,groupSortOrder"
                                                           ascending:YES
                                                       withPredicate:nil
                                                             groupBy:@"groupTypeName"
                                                            delegate:self];
    
    return fetchedResultsController;

我尝试了各种组合,但无法获得每个表格视图部分(联系人组组)和每个表格视图部分的排序顺序。我知道您可以添加逗号分隔的排序属性,但我就是无法正确组合。任何人都知道是否有可能使用 MagicalRecord 实现我想要的,或者我是否必须滚动一些非 MR 代码。

提前感谢您的任何意见和帮助!

更新:

这是由 Core Data 生成的 SQL:

CoreData: sql: 
SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZGROUPID,  t0.ZGROUPNAME, t0.ZGROUPSORTORDER, 
t0.ZGROUPTYPE, t0.ZGROUPTYPENAME, t0.ZGROUPTYPESORTORDER 
FROM ZTCONTACTGROUP t0 
ORDER BY t0.ZGROUPTYPESORTORDER, t0.ZGROUPSORTORDER

更新:

所以我尝试了按groupTypeSortOrder 进行分组,现在它可以正常工作了。但是,不是我无法正确显示部分名称,因为它将显示为 groupTypeSortOrder 的数字。有什么想法吗?

- (NSFetchedResultsController *)fetchedResultsController 
    if (!fetchedResultsController) 
        fetchedResultsController = [ContactGroup fetchAllSortedBy:@"groupTypeSortOrder,groupSortOrder"
                                                           ascending:YES
                                                       withPredicate:nil
                                                             groupBy:@"groupTypeSortOrder"
                                                            delegate:self];
    
    return fetchedResultsController;

【问题讨论】:

您有机会检查核心数据生成的 SQL 吗? 是啊,不能承认自己是超级精通SQL的人。但我会在上面添加。 @KyleLeNeau 已添加,见上文。 【参考方案1】:

我还没有使用过 MagicalRecord,但我假设 groupBy: 参数对应于 NSFetchedResultsControllersectionNameKeyPath: 参数。

如果键被指定为sectionNameKeyPath,则获取请求必须具有使用相同键(或生成相同相对顺序的键)的第一个排序描述符。

因此,使用 groupTypeSortOrder 作为第一个排序键并作为groupBy: 参数是正确的方法。

现在,要将组名而不是数字显示为节标题,您可以修改 titleForHeaderInSection 方法,该方法通常如下所示:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section  
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [sectionInfo name];

[sectionInfo name]groupTypeSortOrder 的值,因为它已被指定为sectionNameKeyPath(或groupBy)。如果你像这样修改方法:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section  
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [[[sectionInfo objects] objectAtIndex:0] groupName];

groupName 属性改为显示为节标题。

【讨论】:

是的,我最终也这样做了,在意识到这可能是唯一的方法之后,我只是希望/假设它会自动完成 :)

以上是关于MagicalRecord NSFetchesResultsController 部分分组和排序 + 部分内也是如此的主要内容,如果未能解决你的问题,请参考以下文章

MagicalRecord:后台保存

未找到 MagicalRecord/MagicalRecordDeprecationMacros.h 文件

WatchKit 和 MagicalRecord - 这可能吗?

MagicalRecord 3.0 设置

MagicalRecord 日期解析

Simperium和MagicalRecord