用表视图将两个属性信息添加到单个核心数据实体中的有效方法

时间:2013-11-21 16:55:00

标签: ios objective-c core-data if-statement nsfetchedresultscontroller

我有一个基本的应用程序前提 - 允许用户向4个文本字段提供信息,并使用FetchedResultsController和Core Data在表视图中准确显示该信息。

我在使用两个属性获取相应更新时遇到问题。

我的实体是: 交易(isGiven属性)

场合(dateOfEvent,标题属性)

人(姓名属性)

项目(itemType属性)。

人和物品在这里无关紧要。在View Controller的Save Method中,我调用我的Occasion类,将输入的dateOfEvent和title传递给它。在本课程中,我想要实现的是:

  • 检查标题是否存在。如果没有,请创建一个。如果是,请将其退回。
  • 检查日期是否存在。如果没有,请创建一个。如果是,请将其退回。

日期当前是一个字符串(稍后将更改为NSDate - 我首先测试它)。

我创建了一个复杂的If语句,但它没有恰当地更新Table视图。我们来看一些代码:

场合

+ (Occasion *)occasionWithTitle:(NSString *)title andEnteredDate:(NSString *)date inManagedObjectContext:(NSManagedObjectContext *)context
{
    Occasion *occasion = nil;

    // Creating a fetch request to check whether the name of the person already exists
    NSFetchRequest *eventRequest = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"];
    eventRequest.predicate = [NSPredicate predicateWithFormat:@"title = %@", title];
    NSSortDescriptor *eventSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES];
    eventRequest.sortDescriptors = [NSArray arrayWithObject:eventSortDescriptor];
    NSFetchRequest *dateRequest = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"];
    dateRequest.predicate = [NSPredicate predicateWithFormat:@"dateOfEvent = %@", date];
    NSSortDescriptor *dateSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"dateOfEvent" ascending:YES];
    dateRequest.sortDescriptors = [NSArray arrayWithObject:dateSortDescriptor];
    NSError *error = nil;
    NSArray *occasions = [context executeFetchRequest:eventRequest error:&error];
    NSArray *dates = [context executeFetchRequest:dateRequest error:&error];

    if (occasions)
    {

        if ([occasions count] == 0)
        {
            occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
            occasion.title = title;
            if ([dates count] == 0)
            {
                occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
                occasion.dateOfEvent = date;
            }
            else
            {
                occasion = [dates lastObject];
            }
        }
        else
        {
            occasion = [occasions lastObject];
            if ([dates count] == 0)
            {
                occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
                occasion.dateOfEvent = date;
            }
            else
            {
                occasion = [dates lastObject];
            }
        } 
    }
    else
    {
        // handle error
    }
    return occasion;
}

调用它的save方法是:

Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
Occasion *enteredOccasion = (Occasion *)[Occasion occasionWithTitle:self.occasionTextField.text andEnteredDate:self.dateTextField.text inManagedObjectContext:context];
transaction.occasion = enteredOccasion;

TableView中的fetchRequest只显示“Occasion Names”:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Occasion" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;    
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"dateOfEvent" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];

当我选择一个场合名称时,我会被调到另一个控制器,它向我显示有关该场合的所有信息,包括人名,金额(与交易实体相关的事物),所以我的fetchRequest是:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:managedObjectContext];
fetchRequest.entity = entity;    
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"occasion.dateOfEvent" ascending:NO];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
fetchRequest.fetchBatchSize = 20;
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];

我知道Occasion if语句不太正确 - 也许我只需要一个insertNewObjectForEntityForName,因为它在表视图中创建了各种不准确的结果 - 比如创建多个场合,日期等等。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您的if语句逻辑错误。您只需要一个insertNewObjectForEntityForName以避免重复。

仅当Occasiontitle时不存在dateOfEvent时才能创建NSFetchRequest *r = [NSFetchRequest fetchRequestWithEntityName:@"Occasion"]; r.predicate = [NSPredicate predicateWithFormat:@"title = %@ OR dateOfEvent = %@", title,date]; NSArray *matched = [context executeFetchRequest:eventRequest error:&error]; if (matched) { if ([matched count] == 0) { occasion = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context]; occasion.dateOfEvent = date; occasion.title = title } else { occasion = [matched lastObject]; } } else { // handle error } 逻辑应该是:

dateOfEvent

这意味着特定日期或标题只允许一次,这在现实世界中没有多大意义。
如果您想确保titleOR的事件尚不存在,只需将AND替换为title

注意:我的解决方案没有考虑到如果找到现有场合,那就是与Occasion匹配的场合(我认为没关系)。

修改
看完你的评论后,我不太清楚你试图完成什么?

如果您需要OccasionOccurrence实体在标题上是唯一的(按标题出现的群组场合),并且有许多日期,则需要更改模型才能支持此功能。
< / p>

使用date(以及您出现时需要的任何其他属性)向模型添加date实体。
而不是Occasion实体上的OccasionOccurrence属性,而是添加与OccasionOccurrence的多对多关系

现在,在创建Occasion(而非NSFetchRequest *r = [NSFetchRequest fetchRequestWithEntityName:@"OccasionOccurrence"]; r.predicate = [NSPredicate predicateWithFormat:@"occasion.title = %@ AND dateOfEvent = %@", title,date]; )时,请检查是否存在以下任何记录:

{{1}}

如果获取返回任何结果,那么这是一个重复的事件(或者如果你在同一天有很多生日,则不会。)

正如你所看到的,目前尚不清楚你想要完成什么。