4

我刚刚安装了框架 restkit 0.9.3 并按照讨论板示例进行操作。好吧,一切都很好,但是当我尝试使用 Core Data 时,即使在声明了他的 primaryKeyAttribute (userID) 之后,我的 User NSManagedObject 类仍在复制。例如,当我向我的网络服务器发送登录请求时,我返回{"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 回答