FetchRequest 不返回通过 RestKit 0.2 获取的 NSManagedObjects

Posted

技术标签:

【中文标题】FetchRequest 不返回通过 RestKit 0.2 获取的 NSManagedObjects【英文标题】:FetchRequest does not return NSManagedObjects fetched via RestKit 0.2 【发布时间】:2016-03-30 22:28:10 【问题描述】:

我遇到以下问题:我使用 RestKit 从 REST Api 获取对象。对象映射有效,我可以从 RK 调试器输出中看到。但是,当我之后执行 fetch 请求时,结果为空。我说的是 NSManagedObjects。我有以下设置。

1:Restkit 和 Coredata 堆栈初始化:

NSError *error;
NSURL *baseURL = [NSURL URLWithString:@"https://mfihost.us/gocoffee/api/V1/"];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
[objectManager.HTTPClient setDefaultHeader:@"Token" value:[NSString stringWithFormat:@"%@",[FBSDKAccessToken currentAccessToken].tokenString]];

objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
//[RKObjectManager setSharedManager:objectManager];
[FetchRequests registerFetchRequests:objectManager];
[Descriptors registerDescriptors:objectManager];
[managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore *persistentStore = [managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, @"Failed to add inmemory store with error: %@", error);
[managedObjectStore createManagedObjectContexts];
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];

2:调用从服务器获取对象并随后执行获取请求:

[[RKObjectManager sharedManager]
     postObject:nil path:@"/gocoffee/api/V1/login/ios"
     parameters:nil
     success: ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
         NSLog(@"Objects have been saved in core data.");
         NSManagedObjectContext *managedObjCtx = [RKManagedObjectStore defaultStore].mainQueueManagedObjectContext;

        // Shout* sh=[managedObjCtx insertNewObjectForEntityForName:@"Shout"];
        // sh.inviterUserId=@"22223";

         NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
         NSEntityDescription *entity = [NSEntityDescription entityForName:@"Shout" inManagedObjectContext:managedObjCtx];
         [fetchRequest setEntity:entity];

         NSError *error = nil;
         NSArray *result = [managedObjCtx executeFetchRequest:fetchRequest error:&error];

         if (error) 
             NSLog(@"Unable to execute fetch request.");
             NSLog(@"%@, %@", error, error.localizedDescription);

          else 
             NSLog(@"%@", result);
         




         completionBlock();
     
     failure: ^(RKObjectRequestOperation *operation, NSError *error) 
         RKLogError(@"Load failed with error: %@", error);
     ];

虽然服务器返回对象并且这些对象通过使用 RKEntityMappings 和相应的响应描述符正确映射,但获取结果为空。令人困惑的是,如果我取消注释这两行 //Shout * ....(即手动将托管对象插入到上下文中),那么该对象将由 fetch 请求获取。因此,获取请求应该可以正常工作。 我现在正在寻找年龄可能是什么问题。可能是我调用了错误的上下文或其他什么?顺便说一句:core-data 多线程调试开启,没有报错,即没有“AllThatIsLeftToUsIsHonor”错误。

上例对应的路由是:

[objectManager.router.routeSet
     addRoute:[RKRoute routeWithName:@"loginAndOrSignup"
                         pathPattern:@"login/IOS"
                              method:RKRequestMethodPOST]
     ];

描述符看起来像(示例):

[objectManager addResponseDescriptor:
     [RKResponseDescriptor responseDescriptorWithMapping:[shoutMapping inverseMapping]
                                                  method:RKRequestMethodPOST
                                             pathPattern: @"login/IOS"
                                                 keyPath:@"response.incomingshoutapplications"
                                             statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
      ]
     ];

喊映射如下:

RKEntityMapping *shoutMapping = [RKEntityMapping mappingForEntityForName:@"Shout" inManagedObjectStore:managedObjectStore];
    shoutMapping.identificationAttributes = @[ @"id" ];
    [shoutMapping addAttributeMappingsFromDictionary:@
                                                       @"id" : @"id",
                                                       @"inviterUserId" : @"inviterUserId",
                                                       @"eventType" : @"eventType",
                                                       @"eventTime" : @"eventTime",
                                                       @"locationLat" : @"locationLat",
                                                       @"locationLng" : @"locationLng",
                                                       @"radius" : @"radius",
                                                       @"targetGender" : @"targetGender",
                                                       @"state" : @"state",
                                                       @"buddyOnly" : @"buddyOnly",
                                                       @"timeCreated" : @"timeCreated"
                                                       
     ];

“manager”就是上面那个,managedObjectStore 是 manager.managedObjectStore 所有映射和描述符都设置在另一个由 [Descriptors registerDescriptors:objectManager] 调用的方法中; (见第一段代码)

【问题讨论】:

显示映射代码和一些日志,它在末尾显示映射对象 【参考方案1】:

问题可能是您使用的是inverseMapping。这主要用于请求映射,因为它是创建NSMutableDictionary 实例的映射,这不是您想要的。

所以,我期望发生的是响应成功映射,但映射到普通对象,而不是托管对象,然后您将结果丢弃。

改成

... responseDescriptorWithMapping:shoutMapping ...

【讨论】:

抱歉回复晚了....我会尽快尝试并告诉你它是否有效:-) 但是已经谢谢...

以上是关于FetchRequest 不返回通过 RestKit 0.2 获取的 NSManagedObjects的主要内容,如果未能解决你的问题,请参考以下文章

CoreData事务记录查询(Query)中NSPersistentHistoryTransaction.fetchRequest总返回nil的解决

CoreData事务记录查询(Query)中NSPersistentHistoryTransaction.fetchRequest总返回nil的解决

另一种创建 NSPersistentHistoryChangeRequest.fetchRequest 过滤的方法

另一种创建 NSPersistentHistoryChangeRequest.fetchRequest 过滤的方法

NSArray 作为核心数据 fetchRequest 中的参数

NSfetchRequest 啥都不返回