在 Swift 中执行 Restkit addFetchRequestBlock 以进行孤儿删除
Posted
技术标签:
【中文标题】在 Swift 中执行 Restkit addFetchRequestBlock 以进行孤儿删除【英文标题】:Executing Restkit addFetchRequestBlock in Swift for orphan deletion 【发布时间】:2015-08-25 16:22:57 【问题描述】:(更新:更新代码以实现以下 Wain 的一些建议。)
我一直在努力解决以下问题:我有一个应用程序 - 在 Swift 中 - 使用 Restkit 连接到一个 API,以便在添加/更新事件时下拉事件。下面是一些实现的例子。
API JSON:
[
id: 7,
title: "Event 1",
description: "Lorem ipsum dolor...",
,
id: 8,
title: "Event 2",
description: "Lorem ipsum dolor...",
]
AppDelegate:
// Setting up object manager
let baseURL = NSURL(string: "http://url.com")
var objectManager = RKObjectManager(baseURL: baseURL)
objectManager.managedObjectStore = managedObjectStore
// Initialize managed object model and store
var managedObjectModel = NSManagedObjectModel.mergedModelFromBundles(nil)
managedObjectStore = RKManagedObjectStore(managedObjectModel: managedObjectModel)
objectManager.managedObjectStore = managedObjectStore
// Complete CoreData stack initialization
managedObjectStore.createPersistentStoreCoordinator()
let storePath = RKApplicationDataDirectory().stringByAppendingPathComponent("MyApp.sqlite")
let seedPath = NSBundle.mainBundle().pathForResource("RKSeedDatabase", ofType: "sqlite")
var error:NSError?
var persistantStore = managedObjectStore.addSQLitePersistentStoreAtPath(storePath, fromSeedDatabaseAtPath: seedPath, withConfiguration: nil, options: nil, error: nil)
// Creating the managed object contexts
managedObjectStore.createManagedObjectContexts()
// Configure a managed object cache to ensure we don't create duplicate objects
managedObjectStore.managedObjectCache = RKInMemoryManagedObjectCache(managedObjectContext: managedObjectStore.persistentStoreManagedObjectContext)
// Mapping events to Restkit
var eventsMapping = RKEntityMapping(forEntityForName: "Event", inManagedObjectStore: managedObjectStore)
eventsMapping.identificationAttributes = ["eventID", "name", "eventDescription"]
eventsMapping.addAttributeMappingsFromDictionary([
"id":"eventID",
"title":"name",
"description":"eventDescription"
])
// Response descriptor for Events
let eventsDescriptor = RKResponseDescriptor(mapping: eventsMapping, method: RKRequestMethod.GET, pathPattern: "/api/v1/events", keyPath: nil, statusCodes: NSIndexSet(index:200))
// Registering mappings with object manager
objectManager.addResponseDescriptorsFromArray([eventsDescriptor])
数据库模型中的更新方法:
class func runUpdates(completion:(updated:Bool) -> Void)
RKObjectManager.sharedManager().getObjectsAtPath("/api/v1/events", parameters: nil,
success: operation, mappingResult in
completion(updated:true)
,
failure: operation, error in
completion(updated:false)
)
到目前为止,这实际上工作得很好:Restkit 从 API 中提取事件并将它们保存到 Core Data 中,更新更改的事件等很有用。唯一不做的就是删除孤立的事件,所以如果事件在服务器上被删除,它仍保留在我的本地数据中。不好。
所以在谷歌搜索和谷歌搜索并阅读其他 SO 线程之后,第一个想法是如果它是一个 POST 请求,显然 Restkit 不会删除孤儿。只有我肯定在这里发出 GET 请求,如 eventDescriptor 所示。
我遇到的第二件事是显然孤儿只会被 addFetchRequestBlock 删除,所以显然我不应该使用 getObjectsAtPath。在 Swift 中这样的例子非常稀少和缺乏,但是基于 Objective C 的例子我想出了这个来替换 getObjectsAtPath。
RKObjectManager.sharedManager().addFetchRequestBlock (url:NSURL!) -> NSFetchRequest! in
var pathMatcher = RKPathMatcher(pattern: "/api/v1/events")
var match = pathMatcher.matchesPath(url.relativePath, tokenizeQueryStrings: false, parsedArguments: nil)
if(match)
var fetchRequest = NSFetchRequest(entityName: "Event")
return fetchRequest
else
return nil
但是,它根本不起作用:它自动返回 nil(甚至在检查 pathMatcher 以尝试查看它在做什么之前忽略 pathMatcher 周围的任何中断线程)。
很明显,我忽略了某些事情或没有以正确的方式编写方法/做错了什么,有什么想法吗?
【问题讨论】:
【参考方案1】:您对获取请求块的用途有些困惑。它在那里找到可以删除的对象,但它与下载无关。因此,您在配置映射时配置块,然后在您的 GET 完成后开始操作以整理旧(孤立)项目。
顺便说一句,您真的应该在映射上使用identificationAttributes
,并创建一个RKInMemoryManagedObjectCache
用作存储managedObjectCache
。这允许在收到新内容时正确匹配现有项目。
【讨论】:
谢谢你。除了上述建议之外,我还需要为 Restkit 更新一些核心数据堆栈内容(它仍在使用一些默认样板文件)。我在 AppDelegate 中的映射之后放置了获取请求块,并且它确实在 getObjects 方法运行时被调用。从那里,它能够成功删除我从服务器中删除的事件。现在唯一的问题是我在表(NSFetchedResultsController)上遇到断言失败,但超出了原始问题的范围,根据上述更改,我仍然需要先更新一些内容。再次感谢。 只是向可能有类似问题的任何人简单提一下:我在上面的回复评论中提到的断言失败仅仅是由于我的 NSFetchedResultsController 方法中的一个问题,与 RestKit 无关。因此,如果您有类似的问题,请检查您的 didChangeObject / didChangeSection 方法并确保正确定义了相应的 Insert / Delete / etc 情况。以上是关于在 Swift 中执行 Restkit addFetchRequestBlock 以进行孤儿删除的主要内容,如果未能解决你的问题,请参考以下文章
没有带有 cocoapods 和 swift 的模块“RestKit”