4

フレームワークのレストキット 0.9.3 をインストールして、ディスカッション ボードの例に従いました。まあ、すべてうまくいきましたが、Core Data を使用しようとすると、プライマリキー属性 (userID) を宣言した後でも、User NSManagedObject クラスが複製されます。たとえば、Web サーバーにログイン要求を送信すると、{"user":{"id":1, "username":"teste", ...}}.. が返されますが、objectLoader:didLoadObjects を呼び出すたびに新しい行が作成されるようです。

ユーザー テーブル:

ここに画像の説明を入力

コード例:

~ 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);
}

私は何を間違っていますか?

4

3 に答える 3

2

targetObject (RKObjectLoader) に関連する問題を発見しました

/**
 * 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: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];            
        }];
    }];
}
于 2011-10-20T21:18:54.043 に答える
2

RKManagedObjectCache を正しく実装していますか? デバッグのために、単純に nil を返して、それを忘れていました。しばらくして、私にも重複があることがわかりました。

キャッシュは、ローカル オブジェクトをフェッチし、サーバーから返されたオブジェクトと比較することによって機能します。サーバーの応答にないローカル オブジェクトはすべて削除されます。以前のバージョンではフェッチ要求を使用していましたが、新しいバージョンでは手動で要求を実行して実際のオブジェクトを返す必要があります。

nil を返すと、このオブジェクトはキャッシュにないと見なされ、複製が追加されます。この方法を実装してみてください:

+ (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];
}
于 2012-04-30T14:18:01.347 に答える
0

最新の RESTKit バージョン (0.23.2) では、主キーを次のように定義できます。

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

objectId は、コア データ オブジェクトの主キーです。

于 2014-07-28T21:51:38.327 に答える