我有一个基本的App Premise-允许用户使用FetchedResultsController和Core Data在4个文本字段中显示信息,并在表格视图中准确显示该信息。
我遇到一个具有两个属性的实体要适当更新的问题。
我的实体是:
交易(isGiven属性)
场合(dateOfEvent,标题属性)
人(名称属性)
项目(itemType属性)。
这里的人员和项目都无关紧要。在视图控制器的Save方法中,我调用了Occasion类,并将输入的dateOfEvent和标题传递给它。在本课程中,我想要实现的是:
检查标题是否存在。如果没有,请创建一个。如果是,则将其退回。
检查日期是否存在。如果没有,请创建一个。如果是,则将其退回。
该日期当前是一个字符串(稍后将更改为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为:
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,因为它在表视图中创建各种不准确的结果-例如创建多个场合,日期等。
任何帮助,将不胜感激!
最佳答案
您的if
语句逻辑是错误的。您只需要一个insertNewObjectForEntityForName
即可避免重复。
仅在Occasion
或title
不存在的情况下创建一个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
和title
的事件尚不存在,只需将OR
替换为AND
注意:我的解决方案没有考虑到,如果找到一个现有场合,它就是与
title
匹配的场合(我认为这没有关系)。编辑:
阅读您的评论后,我不太清楚您要完成什么?
如果您需要
Occasion
实体在标题上是唯一的(按标题分组发生的场合),并且有很多日期,则需要更改模型以支持此功能。使用
OccasionOccurrence
(以及发生时所需的任何其他属性)将date
实体添加到模型中。代替
date
实体上的Occasion
属性,向OccasionOccurrence
添加一对多关系现在,在创建
OccasionOccurrence
(而不是Occasion
)时,检查是否存在以下记录:NSFetchRequest *r = [NSFetchRequest fetchRequestWithEntityName:@"OccasionOccurrence"];
r.predicate = [NSPredicate predicateWithFormat:@"occasion.title = %@ AND dateOfEvent = %@", title,date];
如果抓取返回的结果不是重复事件(或者同一天有很多生日,则不是)。
如您所见,不清楚您要完成什么。