2012-04-19 4 views
3

В течение последних недель я изучаю Restkit (v0.10.0) и основные данные, и возможности бесконечны с помощью этих замечательных инструментов. Проблема в том, что я немного ошеломлен тем, как увидеть большую картину здесь. И из-за очень быстрого обновления Restkit большая часть учебника/демонстрационного кода устарела и больше не работает должным образом.Интеграция данных рестайлингового ядра с NSManagedObjectContext

Мне удалось получить мой рабочий стол, заполненный данными из моего json на удаленном сервере. Я также разработал, как сделать удаленные данные ведущими в сочетании с кешированием, работающим сейчас, но я борюсь с NSManagedObjectContext/NSEntityDescription (основные данные) и как он работает с Restkit при использовании команд POST.

Если я правильно понял, запись создается в Core Data (после строки комментария // Создать новый экземпляр), после чего эти данные используются для создания запроса POST, чтобы запись была отправлена ​​на сервер.

Этот код используется для создания новой записи на сервере, но когда код выполняется (я вижу запись, создаваемую на моем сервере), но мое табличное представление не обновляется соответствующим образом, представление таблицы не обновляется, и поэтому новая запись будет видна при перезапуске приложения. Вручную обновлять данные с сервера также не помогает.

Надеюсь, кто-то может дать мне несколько указателей, или, может быть, учебник с данными Restkit/core и POST. Благодаря!

- (void)createGoalWithName:(NSString *)name andDescription:(NSString *)goalDescription 
{ 
    Goal* goal = [Goal object]; 
    goal.identifier = 0; 
    goal.name = name; 
    goal.goalDescription = goalDescription; 

    // Create a new instance of the entity managed by the fetched results controller. 
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity]; 
    [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

    [self saveContext]; 

    [[RKObjectManager sharedManager].router routeClass:[Goal class] toResourcePath:@"/api/goals" forMethod:RKRequestMethodPOST]; 

    [[RKObjectManager sharedManager] postObject:goal delegate:self]; 

    [self.tableView reloadData]; 
} 

- (void)saveContext { 
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
    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. 

    You should not use this function in a shipping application, 
    although it may be useful during development. 

    If it is not possible to recover from the error, 
    display an alert panel that instructs the user to quit the application by pressing the Home button. 
    */ 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 
+0

Я смотрел в тот же тип вещи.[Здесь] (http://mobile.tutsplus.com/tutorials/iphone/advanced-restkit-development_iphone-sdk/) - это ссылка на учебное пособие по данным RestKit и Core. – Kent

+0

Да, я тоже видел этот учебник. Проблема в том, что она очень старая, и многие из способов, с которыми работает RestKit, со временем изменились. Спасибо хоть! – Hugo

+0

Думаю, вам нужно будет уточнить, как вы заполняете 'UITableView', если хотите получить ответ. В приведенном выше коде показан механизм предположительной работы, но вы не объясняете, как вы пытаетесь получить эти данные для отображения в таблице. :-) – penfold

ответ

0

Я по-прежнему использую несколько более старую версию Restkit. Но один ключевой элемент состоит в том, что должен быть определен атрибут первичного ключа. Чтобы Restkit мог сохранять локальные хранимые объекты и объекты сервера в синхронизации.

В вашем случае, при определении сопоставлений для объекта цели, вы сделали бы это так: goalMapping.primaryKeyAttribute = @ "identifier";

+0

Tjeerd, спасибо за ответ, но это не проблема. У меня было это заявление в моем коде, но где-то еще. – Hugo

2

Вы должны использовать блоки при использовании RestKit + CoreData и забыть настройки маршрутизатора:

NSString *postUrl = @"/someurl/newelement";  
[ [RKObjectManager sharedManager] loadObjectsAtResourcePath:postUrl usingBlock:^(RKObjectLoader* loader) { 
    loader.serializationMIMEType = RKMIMETypeJSON; 

    loader.delegate = nil; 
    loader.targetObject = nil; 
    loader.method= RKRequestMethodPOST; // change to GET, POST, PUT etc 
}]; 
1

Поскольку вы не включать код пользовательского интерфейса, это трудно полностью диагностировать эту проблему, но одна вещь, может произойти с момента появления обновлений при перезапуске приложения, заключается в том, что вы неправильно синхронизируете изменения между контекстами локального управляемого объекта потока. RestKit имеет свой собственный контекст управляемого объекта, поскольку он не работает в основном потоке пользовательского интерфейса.

Концепция работы с несколькими потоками в Core Data рассматривается в данном документе компании Apple: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html, но суть его в том, что вы должны зарегистрироваться для уведомления NSManagedObjectContextDidSaveNotification и затем вызвать mergeChangesFromContextDidSaveNotification: на управляемом контексте объекта пользовательского интерфейса потока безопасно объедините изменения, сделанные в потоке RestKit.

Имейте в виду, что уведомление будет опубликовано в потоке RestKit, поэтому вам, вероятно, придется запустить обновление в основном потоке пользовательского интерфейса, например. что-то вроде этого в способе получения уведомления:

[self.managedObjectContextForMainThread performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES]; 

Если свойство NSManagedObjectContext* managedObjectContextForMainThread инициализирован правильно, чтобы указать на управляемом контексте объекта пользовательского интерфейса потока.

Надеется, что это помогает (если вы не отказались от RestKit вообще ...)