将过滤器应用于NSFetchedResultsController [英] Applying a filter to NSFetchedResultsController

查看:130
本文介绍了将过滤器应用于NSFetchedResultsController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下工作用于在表上显示引脚列表,并且可以使用操作表成功更改_category。

The following works to display the list of "Pins" on a table and I can change _category using an actionsheet successfully.

我只想显示符合指定类别(例如旅游)的结果,但仍然可以添加没有相同类别的引脚(例如首页) to managedObjectContext。

I want to only show results that match the given category (i.e. Travel), but still be able to add Pins that don't have the same category (i.e. Home) to managedObjectContext.

我尝试了很多方法来使用谓词来过滤获取的数据(通过比较_category和Pin的'category'属性)无效 - 最大的我仍然显示所有我的条目,无论类别,但只允许选择类别的引脚添加。

I have tried many ways to use a predicate to filter the fetched data (by comparing _category to the 'category' property of Pin) to no avail - the furthest I've gotten still showed all of my entries regardless of category but only allowed pins of the chosen category to be added.

这些代码大部分来自CoreData /

Most of this code is from the CoreData/TableView template provided with Xcode.

任何帮助将是非常有用的 - 这是我第一次使用CoreData。

Any help would be incredibly helpful - this is my first time using CoreData.

- (void)setFilter {
//load
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *title = [prefs stringForKey:@"Filter"];
_category = title;

if ([title isEqualToString:@"None"] || title.length < 1) {
    title = [NSString stringWithFormat:@"All Pins"];
}else{
    title = [NSString stringWithFormat:@"%@ Pins", title];
}
self.navigationItem.title = title;

[self.tableView reloadData];
}

///////////////////////////////////////////////////////////////////////////
//
//                            Action Sheet
//
///////////////////////////////////////////////////////////////////////////

- (IBAction)showCategorySheet:(id)sender {
UIActionSheet *popupQuery;
popupQuery = [[UIActionSheet alloc] initWithTitle:@"Category" delegate:self cancelButtonTitle:@"All" destructiveButtonTitle:nil
                                otherButtonTitles:@"Family", @"Friends", @"Home", @"Work", @"Travel", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleDefault;
[popupQuery showInView:self.view];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

NSString *filter;

if (buttonIndex == 0) {
    //Family
    filter = @"Family";
}else if (buttonIndex == 1) {
    //Friends
    filter = @"Friends";
}else if (buttonIndex == 2) {
    //Home
    filter = @"Home";
}else if (buttonIndex == 3) {
    //Work
    filter = @"Work";
}else if (buttonIndex == 4) {
    //Travel
    filter = @"Travel";
}else if (buttonIndex == 5) {
    //None
    filter = @"None";
}
//save
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:filter forKey:@"Filter"];
[self setFilter];
}

///////////////////////////////////////////////////////////////////////////
//
//                               Table
//
///////////////////////////////////////////////////////////////////////////

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0;
}

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

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

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

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
    [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

    NSError *error = nil;
    if (![context save:&error]) {
         // Replace this implementation with code to handle the error appropriately.
         // abort() causes the application to generate a crash log and terminate.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}   
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// The table view should not be re-orderable.
return NO;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    self.detailViewController.detailItem = object;
}
}

///////////////////////////////////////////////////////////////////////////
//
//                           Data Handling
//
///////////////////////////////////////////////////////////////////////////

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

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Pin" 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:@"creationDate" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];

[fetchRequest setSortDescriptors:sortDescriptors];

// 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:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
     // Replace this implementation with code to handle the error appropriately.
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return _fetchedResultsController;
}    

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
       atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
    case NSFetchedResultsChangeInsert:
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
   atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;

switch(type) {
    case NSFetchedResultsChangeInsert:
        [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeUpdate:
        [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"object: %@", [object valueForKey:@"category"]);
NSLog(@"filter: %@", _category);
//time
NSDate *now = [object valueForKey:@"creationDate"];
NSString *formattedTime = [NSString stringWithFormat:@"%@", [self formattedDate:now type:@"date"]];

cell.textLabel.text = [[object valueForKey:@"pinName"] description];
cell.detailTextLabel.text = formattedTime;

if ([[object valueForKey:@"pinPictureThumb"] description].length > 0) {
    NSData *data = [object valueForKey:@"pinPictureThumb"];
    UIImage *img = [[UIImage alloc] initWithData:data];
    cell.imageView.image = img;
}else{
    cell.imageView.image = nil;
}
}


推荐答案

您的fetchedResultsController方法,您需要在您的[fetchRequest setSortDescriptors:sortDescriptors]之后向您的抓取请求添加NSPredicate *对象;

In your fetchedResultsController method you need to add an NSPredicate* object to your fetch request right after your [fetchRequest setSortDescriptors:sortDescriptors]; line and then run your fetch request normally.

NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"category=%@", categoryToFind];
[fetchRequest setPredicate:fetchPredicate];

上面显示的格式是从我的某些代码复制的,因此它可能不是EXACT谓词格式您正在寻找。如果您无法正确格式化谓词,请在这里查看苹果文档: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html

The format I show above is copied from some code of mine, so it may not be the EXACT predicate format you are looking for. If you are having trouble formatting the predicate correctly, check out the apple docs here: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html

还有一些关于格式化谓词的线程。

There are also a bunch of threads on SO about formatting predicates.

这篇关于将过滤器应用于NSFetchedResultsController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆