【问题标题】:RESTKit deleting object when the response is empty响应为空时RESTKit删除对象
【发布时间】:2012-07-16 20:25:15
【问题描述】:

我使用 RESTKit 已经有一段时间了,它更容易加载 json 并将它们保存在数据库中。但是,我有时一直在谷歌上搜索,找不到解决这个问题的方法。

我设置了一个托管对象模型,使得三个不同的实体彼此之间具有直接的一对一关系。我的模型的布局是;

如果我在Friend类上加载对象,它也会根据Friend模型中的映射关系映射到其余两个模型。

假设用户连接了他的 facebook 帐户并链接了帐户,那么很明显 json 响应将包含linkedin 和朋友模型的映射。在这种情况下,json 响应将是;

[
   {
      "name":"foo bar",
      "id":307,
      "facebook":{
         "name":"foo bar",
         "username":"foo.bar.5074",
         "id":"1000013421379389",
         "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
      },
     "linkedin":{
         "name":"foo bar",
         "headline":"some headline",
         "id":"1000013",
         "link":"http://www.linkedin.com/foo.bar",
         "image":"https://linkedin.com/foo-bar.jpg"
      },
      "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
   },
   {
     ... 
    }
  ]

但是,一旦用户链接了 Facebook 和 Linkedin,他也可以通过网站取消链接。因此,如果用户取消链接,则 json 响应将不会具有与通常相同的映射,并且可能不会在 json 响应中包含 facebook 对象或 linkedin 对象,因此响应看起来像,

[
       {
          "name":"foo bar",
          "id":307,
          "facebook":{
             "name":"foo bar",
             "username":"foo.bar.5074",
             "id":"1000013421379389",
             "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
          },
          "picture":"https://fbcdn-profile-a.akamaihd.net/foo-bar.jpg"
       },
       {
         ... 
        }
      ]

如果出现这样的响应,我想为用户删除现有的链接记录。或者可能是如果响应没有 facebook 或两者都没有我想删除本地记录和模型的关联,以响应中为空者为准。

我希望 RESTKit 自动删除关联的对象。我想通过在对象加载器中指定获取请求可以通过 Restkit,但我不太确定。我正在使用加载器模式来加载对象,所以我将在哪里指定获取请求,

已编辑

RKObjectMappingProvider *provider = [RKObjectMappingProvider mappingProvider];
[provider setObjectMapping:[self objectMappingForFriend] forKeyPath:@""];

[provider setObjectMapping:[self objectMappingForFriend] forResourcePathPattern:resourcePath withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {

    return [Friend fetchRequest];

}];

    [[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader){
        loader.mappingProvider = provider;
        loader.delegate = self;
        loader.method = RKRequestMethodGET;
    }];

_我想我这里有多余的代码。 _

有了这个,我希望在响应为空时删除本地存储中的所有对象。但是,它对我不起作用。我不知道我应该如何解决这个问题。

更新时间:当地时间 2012 年 7 月 8 日下午 2:23

self.objectManager = [RKObjectManager objectManagerWithBaseURL:[NSURL URLWithString: @"https://mywebsite"]];
        self.objectManager.client.disableCertificateValidation = YES;
        self.objectManager.client.cachePolicy = RKRequestCachePolicyLoadIfOffline | RKRequestCachePolicyLoadOnError | RKRequestCachePolicyTimeout | RKRequestCachePolicyEtag;
        self.objectManager.requestCache.storagePolicy = RKRequestCacheStoragePolicyPermanently;
        self.objectManager.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
        self.objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"test.sqlite" ];
        self.objectManager.objectStore.cacheStrategy = [RKInMemoryManagedObjectCache new];

现在,设置映射广告加载数据,

RKObjectMappingProvider *provider = [RKObjectMappingProvider mappingProvider];
[provider setObjectMapping:[self objectMappingForFriend] forKeyPath:@""];

[provider setObjectMapping:[self objectMappingForFriend] forResourcePathPattern:resourcePath withFetchRequestBlock:^NSFetchRequest *(NSString *resourcePath) {

    return [Friend fetchRequest];

}];

    [[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader){
        loader.mappingProvider = provider;
        loader.delegate = self;
        loader.method = RKRequestMethodGET;
    }];

更新时间:当地时间 2012 年 7 月 8 日下午 4:11

似乎它正在删除一些无效的一些本地对象,但只有一些对象有引用,即使有空的 json 响应,主模型 Friend 仍然存在。

【问题讨论】:

    标签: objective-c ios core-data restkit


    【解决方案1】:

    您需要在此处配置两个设置。首先,在您的 RKObjectMapping 中,您将 setNilForMissingRelationships 设置为 YES。然后您还需要确保 Core Data 关系具有正确的删除规则(编辑关系时在实用程序面板中)。请参阅this,了解每个删除规则的作用。

    【讨论】:

    • 好的,现在我使用 nullify 规则让它为关系工作,但是如果我想在响应 json 为空的情况下完全删除本地数据怎么办。假设我的 json 是 [],那么我将如何首先删除所有朋友,然后删除与他们关联的记录。
    • 或者下次删除那些没有出现在json中的现有好友。
    • 这是一个不同的问题。简而言之,这取决于您的版本。旧版本解释here。较新的版本,默认为 RKInMemoryManagedObjectCache,但您可能希望切换到 RKFetchRequestManagedObjectCache 用于您的缓存策略。
    • 但是,我该如何使用 RKFetchRequestmanagedObjectCache。你能提供一些简单的例子吗?
    • 我不是代码工厂。这与您第一次提出的问题不同,将问题编辑为另一个问题有点作弊。阅读FAQ可能对您有用
    【解决方案2】:

    我必须假设您使用的是最新版本的 RestKit。所以,试试这行:

    [RKObjectManager sharedManager].objectStore.managedObjectCache = [RKFetchRequestManagedObjectCache new];
    

    对于成功的 GET 请求,它最终会调用 [RKManagedObjectLoader deleteCachedObjectsMissingFromResult:] 来取消缓存您的本地数据。在我之前对您上一个问题的回答中链接到的文章中更好地解释了该原理。

    【讨论】:

    • 我没有用于对象存储的名为 managedObjectCache 的属性。这是 restkit 的最新版本吗?
    • 似乎我可以缓存对象,但当 json 响应为空时仍然无法删除对象。查看我更新的代码。
    • @PauldeLange - 很多人都面临同样的问题。我添加了您上面提到的代码,并且正在使用最新的 Restkit 分支,但无法正常工作。请看看你是否能解决这个问题:stackoverflow.com/questions/13388030/…
    【解决方案3】:

    以下是设置缓存策略的方法

    [RKObjectManager sharedManager].objectStore.cacheStrategy = [RKFetchRequestManagedObjectCache new];
    

    【讨论】:

    • 你在哪里设置这个?每次拨打[[[RKObjectManager sharedManager] loadObjectsAtResourcePath:之前我都应该这样做吗?
    • 不,你只需要在设置 RKObjectManager 和映射时设置一次
    【解决方案4】:

    使用新的 RestKit,这可以使用 fetchRequest 块来完成;

     [[RKObjectManager sharedManager] addFetchRequestBlock:[self fetchRequestBlock]];
    
    
    -(RKFetchRequestBlock)fetchRequestBlock{
      RKFetchRequestBlock fetchRequestBlock = ^NSFetchRequest*(NSURL *url){
        if( [url.relativePath isEqualToString:@"api/app/v1/network_contacts"] ){
          return [NSFetchRequest fetchRequestWithEntityName:@"Person"] ;
        }
        return nil ;
      };
      return fetchRequestBlock;
    }
    

    此方法查询本地数据库并比较远程对象,如果不匹配,则从本地存储中删除对象。

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 2017-06-04
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-02
      相关资源
      最近更新 更多