2015-12-21 29 views
1

我目前使用RestKit版本0.26.0Restkit本地數據映射操作似乎沒有保存到磁盤

我正在執行本地映射操作(它需要一個本地.json文件,並將其解析爲目標c核心數據對象)。我這樣做,像這樣:

/* 
From: 
http://stackoverflow.com/questions/26556883/restkit-sync-data-base-with-local-json-file 
*/ 
NSString* const MIMEType = @"application/json"; 

NSString* resourceName = [route.pathPattern stringByReplacingOccurrencesOfString:@"/" withString:@"--"]; 
NSString* data_filePath = [[NSBundle mainBundle] pathForResource:resourceName ofType:@"json"]; 
NSData *data = [NSData dataWithContentsOfFile:data_filePath]; 

NSError* error = nil; 

id parsedData = [RKMIMETypeSerialization objectFromData:data MIMEType:MIMEType error:&error]; 
if (parsedData == nil && error) { 
    // Parser error... 
} 

RKManagedObjectStore *managedObjectStore = self.objectManager.managedObjectStore; 
RKManagedObjectMappingOperationDataSource *mappingDataSource = [[RKManagedObjectMappingOperationDataSource alloc] 
                   initWithManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext 
                   cache:managedObjectStore.managedObjectCache]; 

static NSMutableArray<RKMapperOperation*>* mapperOperations; 
if (mapperOperations == nil) 
{ 
    mapperOperations = [NSMutableArray array]; 
} 

RKMapperOperation* mapperOperation = [[RKMapperOperation alloc] initWithRepresentation:parsedData 
                    mappingsDictionary:objectMappings]; 

[mapperOperation setMappingOperationDataSource:mappingDataSource]; 

[mapperOperations addObject:mapperOperation]; 

dispatch_async(dispatch_get_main_queue(), ^{ 
    NSError *mappingError = nil; 
    BOOL isMapped = [mapperOperation execute:&mappingError]; 

    if (isMapped && !mappingError) 
    { 
     success(mapperOperation,mapperOperation.mappingResult); 
    } 
    else 
    { 
     failure(mapperOperation,mappingError,false); 
    } 

    NSUInteger mapperOperation_index = [mapperOperations indexOfObject:mapperOperation]; 
    BOOL remove_mapperOperation = (mapperOperation_index < mapperOperations.count); 
    NSCAssert(remove_mapperOperation, @"unhandled"); 
    if (remove_mapperOperation) 
    { 
     [mapperOperations removeObjectAtIndex:mapperOperation_index]; 
    } 
}); 

return mapperOperation; 

通過請求達到其成功塊的時候,一切似乎是爲了 - 讓我的所有對象解析如何我想,通過映射的結果通過。不僅如此,我還可以使用NSFetchRequest和我的RKObjectManagermanagedObjectStore.mainQueueManagedObjectContext來獲取這些對象。例如,下面的回報我的身份驗證令牌:

-(QDAuthenticationToken*)fetchAuthenticationTokenFromStore 
{ 
NSManagedObjectContext* context = [QDNetworkManager sharedInstance].objectManagerMainQueueManagedObjectContext; 

__block QDAuthenticationToken* authenticationToken = nil; 

NSFetchRequest *fetchRequest = [NSFetchRequest new]; 
[fetchRequest setFetchLimit:1]; 
[fetchRequest setEntity:[QDAuthenticationToken entityInManagedObjectContext:context]]; 

[context performBlockAndWait:^{ 

    NSError* fetchError = nil; 
    NSArray* fetchedObjects = [context executeFetchRequest:fetchRequest error:&fetchError]; 

    kRUConditionalReturn(fetchError != nil, YES); 
    kRUConditionalReturn(fetchedObjects.count != 1, NO); 

    authenticationToken = kRUClassOrNil(fetchedObjects.firstObject, QDAuthenticationToken); 

}]; 

return authenticationToken; 
} 

此方法將返回可靠我QDAuthenticationToken的單個實例我在覈心數據,我在一個應用程序的生命週期映射到一個核心數據之後。不幸的是,一旦我殺了應用程序,並嘗試上述獲取,然後返回零。

儘管肯定還有其他可能的解釋,但這導致我相信這些RKMapperOperation實例沒有成功將這些對象寫入磁盤。任何人都可以提供任何幫助嗎?

我也可以提供我的代碼來設置RKObjectManager,但我在一些其他項目中使用restkit,它們的設置代碼完全相同,所以我非常懷疑問題是我的對象管理器的設置。

****更新與正確答案,由於北斗星的評論****

/* 
From: 
http://stackoverflow.com/questions/26556883/restkit-sync-data-base-with-local-json-file 
*/ 
NSString* const MIMEType = @"application/json"; 

NSString* resourceName = [route.pathPattern stringByReplacingOccurrencesOfString:@"/" withString:@"--"]; 
NSString* data_filePath = [[NSBundle mainBundle] pathForResource:resourceName ofType:@"json"]; 
NSData *data = [NSData dataWithContentsOfFile:data_filePath]; 

NSError* error = nil; 

id parsedData = [RKMIMETypeSerialization objectFromData:data MIMEType:MIMEType error:&error]; 
if (parsedData == nil && error) { 
    // Parser error... 
} 

RKManagedObjectStore *managedObjectStore = self.objectManager.managedObjectStore; 
NSManagedObjectContext* context = managedObjectStore.mainQueueManagedObjectContext; 
RKManagedObjectMappingOperationDataSource *mappingDataSource = [[RKManagedObjectMappingOperationDataSource alloc] 
                   initWithManagedObjectContext:context 
                   cache:managedObjectStore.managedObjectCache]; 

static NSMutableArray<RKMapperOperation*>* mapperOperations; 
if (mapperOperations == nil) 
{ 
    mapperOperations = [NSMutableArray array]; 
} 

RKMapperOperation* mapperOperation = [[RKMapperOperation alloc] initWithRepresentation:parsedData 
                    mappingsDictionary:objectMappings]; 

[mapperOperation setMappingOperationDataSource:mappingDataSource]; 

@synchronized(mapperOperations) { 
    [mapperOperations addObject:mapperOperation]; 
} 

dispatch_async(dispatch_get_main_queue(), ^{ 

    __block BOOL operationSuccess = false; 
    __block NSError* operationError = nil; 
    [context performBlockAndWait:^{ 

     NSError *mappingError = nil; 
     BOOL isMapped = [mapperOperation execute:&mappingError]; 

     if ((isMapped == false) || 
      (mappingError != nil)) 
     { 
      operationError = mappingError; 
      return; 
     } 

     NSError* saveError = nil; 
     BOOL saveSuccess = [context saveToPersistentStore:&saveError]; 

     if ((saveSuccess == false) || 
      (saveError != nil)) 
     { 
      operationError = saveError; 
      return; 
     } 

     operationSuccess = YES; 

    }]; 

    if ((operationSuccess == TRUE) && 
     (operationError == nil)) 
    { 
     success(mapperOperation,mapperOperation.mappingResult); 
    } 
    else 
    { 
     failure(mapperOperation,operationError,false); 
    } 


    @synchronized(mapperOperations) { 
     NSUInteger mapperOperation_index = [mapperOperations indexOfObject:mapperOperation]; 
     BOOL remove_mapperOperation = (mapperOperation_index < mapperOperations.count); 
     NSCAssert(remove_mapperOperation, @"unhandled"); 
     if (remove_mapperOperation) 
     { 
      [mapperOperations removeObjectAtIndex:mapperOperation_index]; 
     } 
    } 
}); 

return mapperOperation; 

回答

1

RKMapperOperation不知道的情況下或保存任何東西。當你執行這個操作時是執行一個映射,那就是全部。

RKManagedObjectMappingOperationDataSource創建對象並在請求時將它們插入到上下文中。這些對象在映射期間由RKMapperOperation進行更新。之後數據源不會被要求保存 - 數據源或映射器操作完成後不保存數據源的責任。

因此,在映射器操作完成後,您需要明確地保存上下文(以及取決於您正在使用的上下文的任何父項)。

您的提取請求正常工作,因爲它不需要在返回對象之前保存上下文。

+0

感謝您的及時回覆,這正是我需要的信息來解決這個問題。爲了完整起見,我應該在我的問題中發佈更新後的代碼嗎?我不太熟悉Stack Overflow的最佳實踐。 –

+0

你可以,如果你想,沒有硬性規則 – Wain