我有一个基本的应用程序前提 - 允许用户向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,因为它在表视图中创建了各种不准确的结果 - 比如创建多个场合,日期等等。
任何帮助将不胜感激!
答案 0 :(得分:1)
您的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
实体在标题上是唯一的(按标题出现的群组场合),并且有许多日期,则需要更改模型才能支持此功能。
< / p>
使用date
(以及您出现时需要的任何其他属性)向模型添加date
实体。
而不是Occasion
实体上的OccasionOccurrence
属性,而是添加与OccasionOccurrence
的多对多关系
现在,在创建Occasion
(而非NSFetchRequest *r = [NSFetchRequest fetchRequestWithEntityName:@"OccasionOccurrence"];
r.predicate = [NSPredicate predicateWithFormat:@"occasion.title = %@ AND dateOfEvent = %@", title,date];
)时,请检查是否存在以下任何记录:
{{1}}
如果获取返回任何结果,那么这是一个重复的事件(或者如果你在同一天有很多生日,则不会。)
正如你所看到的,目前尚不清楚你想要完成什么。