这在我的项目中非常适合我。
在函数 updateEnglishNewsListener(:) 中,这里的参数数据在任意对象中,我进一步将其转换为 json 格式以保存。
Core Data 使用线程(或序列化队列)限制来保护托管对象和托管对象上下文(请参阅 Core Data 编程指南)。这样做的结果是,上下文假定默认所有者是分配它的线程或队列——这由调用其 init 方法的线程确定。因此,您不应该在一个线程上初始化上下文,然后将其传递给另一个线程。
一共有三种
1. ConfinementConcurrencyType
2. PrivateQueueConcurrencyType
3. MainQueueConcurrencyType
MainQueueConcurrencyType 创建一个与主队列关联的上下文,非常适合与 NSFetchedResultsController 一起使用。
在 updateEnglishNewsListener(:) 函数中,参数数据是您的输入。 (数据->您要更新的数据。)
private func updateEnglishNewsListener(data: [AnyObject] ){
//Here is your data
let privateAsyncMOC_En = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
// The context is associated with the main queue, and as such is tied into the application’s event loop, but it is otherwise similar to a private queue-based context. You use this queue type for contexts linked to controllers and UI objects that are required to be used only on the main thread.
privateAsyncMOC_En.parent = managedObjectContext
privateAsyncMOC_En.perform{
// The perform(_:) method returns immediately and the context executes the block methods on its own thread. Here it use background thread.
let convetedJSonData = self.convertAnyobjectToJSON(anyObject: data as AnyObject)
for (_ ,object) in convetedJSonData{
self.checkIFNewsIdForEnglishAlreadyExists(newsId: object["news_id"].intValue, completion: { (count) in
if count != 0{
self.updateDataBaseOfEnglishNews(json: object, newsId: object["news_id"].intValue)
}
})
}
do {
if privateAsyncMOC_En.hasChanges{
try privateAsyncMOC_En.save()
}
if managedObjectContext.hasChanges{
try managedObjectContext.save()
}
}catch {
print(error)
}
}
}
检查coredata中是否已经存在数据以避免冗余数据。 Coredata 没有主键概念,所以我们依次检查数据是否已经存在于 coredata 中。当且仅当更新数据已存在于 coredata 中时,才会更新数据。这里 checkIFNewsIdForEnglishAlreadyExists(:) 函数返回 0 或 value 。如果它返回 0,则数据不保存在数据库中,否则保存。我正在使用完成句柄来了解新数据或旧数据。
private func checkIFNewsIdForEnglishAlreadyExists(newsId:Int,completion:(_ count:Int)->()){
let fetchReq:NSFetchRequest<TestEntity> = TestEntity.fetchRequest()
fetchReq.predicate = NSPredicate(format: "news_id = %d",newsId)
fetchReq.fetchLimit = 1 // this gives one data at a time for checking coming data to saved data
do {
let count = try managedObjectContext.count(for: fetchReq)
completion(count)
}catch{
let error = error as NSError
print("\(error)")
completion(0)
}
}
根据需要将旧数据替换为新数据。
private func updateDataBaseOfEnglishNews(json: JSON, newsId : Int){
do {
let fetchRequest:NSFetchRequest<TestEntity> = TestEntity.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "news_id = %d",newsId)
let fetchResults = try managedObjectContext.fetch(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) as? [TestEntity]
if let fetchResults = fetchResults {
if fetchResults.count != 0{
let newManagedObject = fetchResults[0]
newManagedObject.setValue(json["category_name"].stringValue, forKey: "category_name")
newManagedObject.setValue(json["description"].stringValue, forKey: "description1")
do {
if ((newManagedObject.managedObjectContext?.hasChanges) != nil){
try newManagedObject.managedObjectContext?.save()
}
} catch {
let saveError = error as NSError
print(saveError)
}
}
}
} catch {
let saveError = error as NSError
print(saveError)
}
}
将任何对象转换为 JSON 以保存在 coredata 中
func convertAnyobjectToJSON(anyObject: AnyObject) -> JSON{
let jsonData = try! JSONSerialization.data(withJSONObject: anyObject, options: JSONSerialization.WritingOptions.prettyPrinted)
let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
if let dataFromString = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
return json
}
return nil
}
希望对您有所帮助。如果有任何困惑,请询问。