【发布时间】: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 周围的任何中断线程)。
很明显,我忽略了某些事情或没有以正确的方式编写方法/做错了什么,有什么想法吗?
【问题讨论】: