2011-10-17 67 views
4

我剛剛安裝了框架restkit 0.9.3並遵循討論板示例。那麼,一切都很好,但是當我嘗試使用核心數據時,即使在聲明他的primaryKeyAttribute(userID)後,我的用戶NSManagedObject類也會重複。例如,當我向我的網絡服務器發送登錄請求時,我返回{"user":{"id":1, "username":"teste", ...}} ..但它似乎在每次調用objectLoader:didLoadObjects時創建一個新行。primaryKeyAttribute不工作Restkit/Core Data

用戶表:

enter image description here

示例代碼:

〜AppDelegate.m didFinishLaunching

RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];  
userMapping.primaryKeyAttribute = @"userID"; 
userMapping.setDefaultValueForMissingAttributes = YES; // clear out any missing attributes (token on logout) 
[userMapping mapKeyPathsToAttributes: 
    @"id", @"userID", 
    @"email", @"email", 
    @"username", @"username", 
    @"password", @"password", 
    nil]; 

[objectManager.mappingProvider registerMapping:userMapping withRootKeyPath:@"user"]; 

〜User.m loginWithDelegate

- (void)loginWithDelegate:(NSObject<UserAuthenticationDelegate>*)delegate { 
    _delegate = delegate; 
    [[RKObjectManager sharedManager] postObject:self delegate:self block:^(RKObjectLoader* loader) { 
     loader.resourcePath = @"/login"; 
     loader.serializationMapping = [RKObjectMapping serializationMappingWithBlock:^(RKObjectMapping* mapping) { 
      [mapping mapAttributes:@"username", @"password", nil];    
     }]; 
    }]; 
} 

〜User.m didLoadObjects(RKObjectLoaderDelegate)

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray *)objects { 

    if ([objectLoader wasSentToResourcePath:@"/login"]) { 
     [self loginWasSuccessful]; 
    } 

    NSLog(@"number of user rows: %i", [User findAll].count); 
} 

我在做什麼錯?

+0

也許應該叫 - (NSManagedObject *)findOrCreateInstanceOfEntity: (NSEntityDescription *)實體withPrimaryKeyAttribute: (的NSString *)primaryKeyAttribute andValue:(ID)primaryKeyValue; ? – mateusmaso

回答

2

您是否正確實施RKManagedObjectCache?對於調試,我只是簡單地返回零而忘記了這一點。過了一會兒,我發現我也有重複。

緩存的工作原理是獲取本地對象並與服務器返回的對象進行比較。任何不在服務器響應中的本地對象都將被刪除。在早期版本中,它使用了獲取請求,但在較新版本中,您必須手動執行請求並返回實際對象。

如果你返回零,它認爲這個對象不在你的緩存中,並會添加一個副本。嘗試實施這種方法:

+ (NSManagedObject *)findInstanceOfEntity:(NSEntityDescription *)entity 
       withPrimaryKeyAttribute:(NSString *)primaryKeyAttribute 
           value:(id)primaryKeyValue 
       inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext 

例如:

+ (NSManagedObject *)findInstanceOfEntity:(NSEntityDescription *)entity 
       withPrimaryKeyAttribute:(NSString *)primaryKeyAttribute 
           value:(id)primaryKeyValue 
       inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext { 

    NSFetchRequest* request = [[NSFetchRequest alloc] init]; 
    [request setEntity: entity]; 
    [request setFetchLimit: 1]; 
    [request setPredicate:[NSPredicate predicateWithFormat:@"%K = %@", primaryKeyAttribute, primaryKeyValue]]; 

    NSArray *results = [NSManagedObject executeFetchRequest:request inContext: managedObjectContext]; 
    if ([results count] == 0) 
    { 
    return nil; 
    } 
    return [results objectAtIndex:0]; 
} 
2

我發現

/** 
* The target object to map results back onto. If nil, a new object instance 
* for the appropriate mapping will be created. If not nil, the results will 
* be used to update the targetObject's attributes and relationships. 
*/ 

所以,當我將它設置爲nil的postObject調用findOrCreateInstanceOfEntity相關targetObject(RKObjectLoader)問題:withPrimaryKeyAttribute:andValue

- (void)loginWithDelegate:(NSObject<UserAuthenticationDelegate>*)delegate { 
    _delegate = delegate; 
    [[RKObjectManager sharedManager] postObject:self delegate:self block:^(RKObjectLoader* loader) { 
     loader.resourcePath = @"/login"; 
     loader.targetObject = nil; 
     loader.serializationMapping = [RKObjectMapping serializationMappingWithBlock:^(RKObjectMapping* mapping) { 
      [mapping mapAttributes:@"username", @"password", nil];    
     }]; 
    }]; 
} 
+0

那麼,如果你不將它設置爲nil,導致該帖子創建一個重複的對象,那麼targetObject的設置是什麼?我會認爲,如果targetObject被設置爲任何東西,它將被設置爲首先更新的對象... – leftspin

0

由於採用最新版本RESTKit(0.23.2),你可以這樣定義主鍵:

[_mapping addAttributeMappingsFromDictionary:@{ @"id" : @"objectId", @"name" : @"name" }]; 
[_mapping setIdentificationAttributes:@[ @"objectId" ]]; 

而objectId是核心數據對象上的主鍵。

相關問題