2012-12-06 44 views
8

我很想知道什麼最好的方法是在RestKit 0.20中創建一個新的NSManagedObject?目前我的代碼看起來像這樣:RestKit 0.20 - 創建新的NSManagedObject的首選方法是什麼?

#pragma mark - navigation buttons 

- (void)createButtonDidTouch 
{ 
    // create new album object  
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
    NSManagedObjectContext *parentContext = RKObjectManager.sharedManager.managedObjectStore.mainQueueManagedObjectContext; 
    context.parentContext = parentContext; 
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Album" inManagedObjectContext:parentContext]; 
    Album *newAlbum = [[Album alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context]; 

    // pass object to create view to manipulate 
    AlbumCreateViewController *createViewController = [[AlbumCreateViewController alloc] initWithData:newAlbum]; 
    createViewController.delegate = self; 
    createViewController.managedObjectContext = context; 

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:createViewController]; 
    navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 

    [self presentViewController:navController animated:YES completion:nil]; 
} 

#pragma mark - create view controller delegate 

- (void)createViewControllerDidSave:(NSManagedObject *)data 
{ 
    // dismiss the create view controller and POST 

    // FIXME: add restkit code to save the object 
    NSLog(@"save the object..."); 

    NSDictionary *userInfo = [KeychainUtility load:@"userInfo"]; 
    NSString *path = [NSString stringWithFormat:@"/albums/add/%@/%@", userInfo[@"userID"], userInfo[@"apiKey"]]; 

    [RKObjectManager.sharedManager postObject:data path:path parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
     operation.targetObject = data; 
    } failure:^(RKObjectRequestOperation *operation, NSError *error) { 
     NSLog(@"create album error: %@", error); 
    }]; 

    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

- (void)createViewControllerDidCancel:(NSManagedObject *)data 
{ 
    // dismiss the create view controller 

    NSLog(@"delete the object..."); 
    // FIXME: add restkit code to delete the object 

    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

我也很想知道我的責任是保存/刪除此對象。如果我通過RestKit POST到服務器是否保存了託管對象上下文?

如果我決定取消創建過程 - 刪除此對象的首選方法是什麼?

基本上RestKit爲我做了多少事,我應該確保我在做什麼。我還沒有找到很多關於這方面的文件,希望能夠明確。

回答

11

當你給定對象初始化RKManagedObjectRequestOperation,RestKit將獲得該對象的永久對象ID,然後創建其父上下文對象插入上下文中的子管理對象上下文。然後該操作執行HTTP請求以完成並獲得響應。

如果響應成功並且響應映射成功(請注意映射發生在此私有子上下文中),那麼將保存私有子上下文。調用的保存類型取決於savesToPersistentStore屬性的值(請參見http://restkit.org/api/0.20.0/Classes/RKManagedObjectRequestOperation.html#//api/name/savesToPersistentStore)。

YES,上下文通過NSManagedObjectContext分類方法saveToPersistentStore保存遞歸一路回持久性存儲(見http://restkit.org/api/0.20.0/Categories/NSManagedObjectContext+RKAdditions.html)。

NO時,通過vanilla [NSManagedObjectContext save:]消息保存上下文,該消息將「更改」推回到父上下文。在這種情況下,他們將保持本地化,直到您挽回他們。請記住,託管對象上下文父/子層次結構可以與在應用程序中創建一樣長。

如果HTTP請求失敗或在映射過程中出現錯誤,則私有上下文不會保存,並且操作被視爲失敗。這意味着不會將更改保存回原始MOC,從而使對象圖像與操作開始之前一樣(除了要發送的對象,如果臨時的,現在具有永久對象ID但仍未保存)。

+0

那麼我會如何刪除這個對象 - 假設我使用上面的代碼創建了對象,但沒有觸發POST請求 - 而是取消/關閉了「創建」視圖控制器?只通過我的本地NSMangedObjectContext? –

+3

在上面的代碼中,它被插入到上下文中,但未保存。你可以從解除視圖控制器的上下文中刪除它。但是我建議你不要直接將對象插入到'managedObjectStore.mainQueueManagedObjectContext'中,而是在繼續創建控制器並將其分配給控制器時創建一個子託管對象上下文。你可以做的只是讓MOC在你取消時解除分配。 –

+0

是否有創建子上下文的快捷方式?在我記得使用像[Album createObject]之類的東西之前 - 或者類似的東西。 –

3

你這樣做的方式應該可行(每次調用每個VC中的MOC),但不是「推薦」。

蘋果建議,就像任何核心數據應用程序,是「傳遞接力棒」的風格。

嵌套上下文使它比以往任何時候都更重要的是你採取 「接力棒」訪問上下文的方式(通過從一個視圖控制器通過上下文 到下一個),而不是從取回 直接應用程序委託。

在這裏看到: http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/_index.html

關於你的第二個問題,RestKit應管理保存/更新後的API調用的成功,你的核心數據堆棧,如果一切都順利映射/設置。

從布雷克RK創作者:

如果POST或PUT一個核心數據對象,RK獲得永久對象爲它 ID,然後創建一個次級管理對象的上下文,觸發 該請求,並且映射響應(如果可能的話)。如果響應和 映射成功,則將基於savingToPersistentStore的值將其保存回父代 上下文或一直返回到持久性存儲(即進入SQLite) 。