iPhone按日期排序核心数据 NSFetchedResultsController
我正在开发的程序是“CoreDataBooks”的修改版本,取自Apple iPhone示例代码。在“CoreDataBooks”中有一个作者列表,其中一些人拥有多本书。设置了导航控制器,各个部分按作者姓名划分。每个部分都有每个作者的书籍列表。
所以我拿了这段代码,并尝试制作一个按部分排列的名称列表。我的实体称为“患者”。每个实体都有属性 myDate 和 myName,以及其他一些属性。我想按 myDate 排列各个部分,每个部分中都有一个名称列表,所有这些都具有相同的日期。
我在使用 NSFetchedResultsController 方法时遇到困难。当使用日期选择器创建日期时,它们都有一个时间戳。这个时间戳使它们不同,如果您在sectionNameKeyPath方法中按myDate排序,它们将被放置在单独的部分中。
我在网上进行了相当广泛的搜索,并提出了以下解决方案。您创建另一个瞬态属性,即 NSString,然后使用它对各部分进行排序。这是通过创建日期格式化程序来完成的,如下所示。我包含了 NSString 的 setter 以及 NSFetchedResultsController 方法。
任何帮助将不胜感激。
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
PatientsAppDelegate*appDelegate=[[UIApplication sharedApplication]delegate];
NSManagedObjectContext*managedObjectContext=appDelegate.managedObjectContext;
// Create and configure a fetch request with the Book entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Patient" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array.
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myDate" ascending:YES];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:dateDescriptor, nameDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// NSLog(@"%@",myFormattedDate);
// Create and initialize the fetch results controller.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"transactionDay"
cacheName:@"Root"];
self.fetchedResultsController = aFetchedResultsController;
fetchedResultsController.delegate = self;
// Memory management.
[aFetchedResultsController release];
[fetchRequest release];
[dateDescriptor release];
[nameDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
- (NSString *)transactionDay{
[self willAccessValueForKey:@"transactionDay"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM dd,yyyy"];
NSString*someString=[dateFormatter stringFromDate:[self valueForKey:@"myDate"]];
[self didAccessValueForKey:@"transactionDay"];
return someString;
}
我收到的当前错误是“实体患者对于键“transactionDay”不符合键值编码”
再次感谢。
The program I am working on is a modified version of "CoreDataBooks", taken from Apple iPhone sample code. In "CoreDataBooks" there is a list of authors, some of whom have multiple books. A navigation controller is set up, with the sections divided up by author name. In each section, there is a list of books for each author.
So I took this code and am trying to make a list of names, arranged by section. My entity is called "Patient". Each entity has attributes myDate and myName, as well as a few others. I want to arrange sections by myDate, with a list of names in each section, all of which have the same date.
I am having difficulty with the NSFetchedResultsController method. When the dates are created using a date picker, they all have a timestamp. This timestamp makes them different, and they will be placed into separate sections if you sort by myDate in the sectionNameKeyPath method.
I did fairly extensive searching online, and came up with the solution below. You create another transient attribute, an NSString, and then use it to sort the sections. This is done by creating a date formatter, which is shown below. I include my setter for my NSString, as well as the NSFetchedResultsController method.
Any help will be greatly appreciated.
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
PatientsAppDelegate*appDelegate=[[UIApplication sharedApplication]delegate];
NSManagedObjectContext*managedObjectContext=appDelegate.managedObjectContext;
// Create and configure a fetch request with the Book entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Patient" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array.
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myDate" ascending:YES];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:dateDescriptor, nameDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// NSLog(@"%@",myFormattedDate);
// Create and initialize the fetch results controller.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"transactionDay"
cacheName:@"Root"];
self.fetchedResultsController = aFetchedResultsController;
fetchedResultsController.delegate = self;
// Memory management.
[aFetchedResultsController release];
[fetchRequest release];
[dateDescriptor release];
[nameDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
- (NSString *)transactionDay{
[self willAccessValueForKey:@"transactionDay"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM dd,yyyy"];
NSString*someString=[dateFormatter stringFromDate:[self valueForKey:@"myDate"]];
[self didAccessValueForKey:@"transactionDay"];
return someString;
}
The current error I am getting is "the entity Patient is not key value coding-compliant for the key "transactionDay""
Thanks, again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
指定
sectionNameKeyPath
时,必须包含要应用瞬态属性的实体属性(即entityAttribute.transientAttribute
)。因此,如果您有一个实体Patient
,其属性myDate
类型为NSDate
:瞬态属性可以在您的
Patient 实现文件,在顶部添加以下内容:
transactionDay
将进一步处理您的myDate
属性,允许您将部分指定为更严格的格式。请注意,NSDateFormatter
是一个相当庞大的初始化对象,因此为了提高效率,提前声明它并稍后引用它可能是值得的。When specifying the
sectionNameKeyPath
, you have to include the entity attribute that you want to apply the transient attribute to ( i.e.,entityAttribute.transientAttribute
). So if you have an entityPatient
with an attributemyDate
of typeNSDate
:The transient attribute can be defined in your
Patient
implementation file by adding the following to the top:transactionDay
will process yourmyDate
attribute further, allowing you to specify sections to stricter formats. Note thatNSDateFormatter
is quite a bulky object to initialise, so it may be worthwhile to declare it earlier and reference it later for efficiency.-transactionDay
方法应该是您在Patient
类上实现的一个属性,然后这个类(我猜是一个视图控制器)可以选择排序或分段基于它。The
-transactionDay
method should be a property that you implement on yourPatient
class, and then this class (a view controller, I'm guessing) can choose to sort or section based upon it.听起来您正在尝试使用尚未在患者对象模型中声明为属性的sectionNameKeyPath 来初始化您的fetchedResultsController。
您能否确认 transactionDay 被定义为 Patient 对象模型中的 NSString 属性?
而且,这听起来有点迂回地实现你想要实现的目标。也许您应该尝试从 NSDate 属性中删除时间戳?我进行了快速搜索,可以找到删除 NSDate 时间戳的可能解决方案
问题的链接是 使用 Objective C/Cocoa 从 NSDate 对象中删除时间组件
Sounds like your are trying to initialise your fetchedResultsController with a sectionNameKeyPath that hasn't been declared as an attribute in your object model for Patient.
Can you confirm that transactionDay is defined as a NSString attribute in your Patient object model?
Also this sounds like a bit of a round about way to go about what you are trying to achieve. Perhaps you should try to remove the timestamp from your NSDate attribute instead? I did a quick search on SO can found this possible solution to removing NSDate's timestamp
The link to the question is Removing time components from an NSDate object using Objective C/Cocoa