核心数据系列成员按姓氏

时间:2016-01-06 12:22:58

标签: ios uitableview core-data

这是我对Core Data的第一次尝试,所以我希望得到你的指导。

我的示例项目非常简单,我想创建一个显示人员列表的iOS应用程序。我正在寻找的是将同一家庭的所有成员聚集在一起。列表中的某些人不属于“家庭”。因此,UITableView将是组和行的混合。

到目前为止,这是我的Modelenter image description here

这里我在上下文中添加数据

    Family *newFamily = [NSEntityDescription insertNewObjectForEntityForName:@“Family” inManagedObjectContext:self.managedObjectContext];
    [newFamily setSurname:[dict objectForKey:@“surname”]];

    NSMutableSet *members = [newTeam mutableSetValueForKey:@"members"];

    for (NSDictionary *member in [dict objectForKey:@"members"]) {
        Member *newMember = [NSEntityDescription insertNewObjectForEntityForName:@"Member" inManagedObjectContext:self.managedObjectContext];
        [newMember setFirstName:[member objectForKey:@"firstName"]];
        [newMember setAge:[member objectForKey:@“age”]];

        [members addObject:newMember];
    }

//Save context ...

UITableViewController中,我能够阅读并显示家庭/群组的名称。我很困惑你如何显示一个部分的所有对象。

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Family" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"surname" ascending:NO];

    [fetchRequest setSortDescriptors:@[sortDescriptor]];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"surname" cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }

    return _fetchedResultsController;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // I DON'T KNOW WHAT TO DO HERE ...
//    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

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

1 个答案:

答案 0 :(得分:1)

首先,您需要修改模型以包含从MemberFamily的反向关系,这可能是“to-one”。说出那个关系“家庭”。 (在这种情况下需要这种反向关系,见下文,但无论您是否认为需要它们,您几乎总是应该包含所有关系的反转。)

接下来,按如下方式修改FRC配置:底层实体应为Member,因为tableView的每一行都代表一个Member对象。 sectionNameKeyPath应该是“family.surname”,因此FRC将根据相关Member对象的surname属性自动将Family个对象放入部分。重要的是FRC的排序顺序与部分匹配(即同一部分中的所有Member个对象必须一起排序),因此修改排序描述符以使用family.surname(那么你可以如果需要,按firstName排序:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Member" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *surnameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"family.surname" ascending:NO];
    NSSortDescriptor *firstNameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:NO];

    [fetchRequest setSortDescriptors:@[surnameSortDescriptor, firstNameSortDescriptor]];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"family.surname" cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }

    return _fetchedResultsController;
}

最后,还有用于将FRC链接到tableView的样板代码(请参阅Apple Docs here)。你缺少的是:

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    if ([[self.fetchedResultsController sections] count] > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    } else
        return 0;
}

您的configureCell方法同样需要确定要使用

显示的正确Member对象
Member *currentMember = [self.fetchedResultsController objectAtIndexPath:indexPath];

请注意,如果Member内有Family个对象,则FRC会记录一条警告消息,因为sectionName将为零。但它会将所有这些组合在一起 - 您可能希望修改titleForHeaderInSection以使用该部分的其他名称。

另请注意,FRC的部分是通过检查每个family.surname对象的Member来确定的。如果Family个对象没有members,那么Family个对象将不会出现在表格视图中(即没有空白部分)。