Основные данные IOS 5, как заставить NSFetchedResultsController возвращать результаты, соответствующие родительскому отношению один ко многим? - PullRequest
0 голосов
/ 24 февраля 2012

Я пытаюсь найти самый простой способ представить ограниченный набор управляемых объектов с Базовыми данными.

У меня есть один пользователь ко многим событиям отношение, определенное в Базовых данных.

Мне нужно, чтобы мои UITableViewControllers отображали результаты для одного пользователя за раз, сохраняя при этом возможность вставлять / удалять события для этого пользователя.Если бы мне просто нужно было отобразить данные, я бы взял NSSet и преобразовал его в источник данных табличного представления. Я хотел бы сохранить возможность добавлять / удалять и редактировать события, но только для текущего активного пользователя.

Я думал об установке моего NSFetchedResultsController в ноль каждый раз, когда мне нужно изменитьпользователь, а затем повторно инициализировать его, как показано ниже.Это сохраняет возможность работать с данными, но требует некоторого свойства для фильтрации данных.

В настоящее время я думаю реализовать это следующим образом: иметь свойство ID, определенное для пользователя, а затем добавить тот же ID ко всем событиям для пользователя. Это позволит мне использоватьNSPredicate для поиска событий пользователя, как определено ниже.

Есть ли альтернативный способ решения моей проблемы с использованием отношений Core Data?Я чувствую, что должно быть, но я не вижу его.

Вот код, который я использую для поиска: я поменяю местами между представлением этого NSFetchedResultsController для частичных результатов и обычным NSFetchedResultsController дляполные результаты.

- (NSFetchedResultsController *)searchFetchedResultsController
{
    if (__searchFetchedResultsController != nil) {
        return __searchFetchedResultsController;
    }

    // Set up the fetched results controller.
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    //    NSString *attributeName = @"type";
    //    //    NSString *attributeValue = [NSString stringWithFormat:@"%i",dateID];
    //    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %i",
    //                              attributeName, 0];
    //    [fetchRequest setPredicate:predicate];
    //    
    //    NSString *attributeName = @"type";
    //    //    NSString *attributeValue = [NSString stringWithFormat:@"%i",dateID];

    NSPredicate *notesPredicate = [NSPredicate predicateWithFormat:@"notes CONTAINS[cd]%@", self.searchString];

    NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd]%@", self.searchString];

    NSPredicate* compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:notesPredicate,namePredicate, nil]];

        [fetchRequest setPredicate:compoundPredicate];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
#warning cache may prevent search results from updating
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"dayID" cacheName:@"SearchResults"];
    self.searchFetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.searchFetchedResultsController 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();
    }
    NSLog(@"found objects: %i",[__searchFetchedResultsController.fetchedObjects count]);

    return __searchFetchedResultsController;
}  

Спасибо за любую помощь!

Ответы [ 2 ]

2 голосов
/ 24 февраля 2012

Ваш подход установки NSFetchedResultsController на nil является надежным.Контроллер полученных результатов должен создаваться лениво, и вы просто устанавливаете его на nil, если вам нужно изменить предикат.

Нет необходимости в вашем собственном поле идентификатора.В своем запросе на выборку для событий просто создайте предикат, например, так:

NSPredicate *predicate = [NSPredicate predicateWithFormat:
   @"user = %@", userObject];

, где «пользователь» будет именем, которое вы дали связи в сущности события.

1 голос
/ 24 февраля 2012

Нет необходимости создавать поле ID в объекте Event для идентификации пользователя. Вы сказали, что у вас уже есть пользователь установки отношения> событие. Отношения идут обоими путями (если вы настроите их таким образом, они называются двунаправленными, и рекомендуется всегда их использовать), поэтому вы можете легко создать NSPredicate, который ищет события, где user = user.

...