在创建了.xcdatamodeld文件之后,需要创建相关的model,之后便是初始化CoreData。一般使用的是NSManagedObjectModel、NSManagedObjectContext、NSPersistentStoreCoordinator。
swift中创建单例:
static let shared:CoreDataManager = {
let instance = CoreDataManager()
return instance
}()
首先,创建model:
根据文件名字来创建model:
//创建model对象,model需要momd
var managedObjectModel:NSManagedObjectModel{
if !(_managedObjectModel != nil){
let modelURL = Bundle.main.url(forResource: dataModelName, withExtension: "momd")
_managedObjectModel = NSManagedObjectModel(contentsOf: modelURL!)
}
return _managedObjectModel!
}
之后是创建coordinator:
根据Model创建coordinator:
//初始化coordinator,需要model
var persistentStoreCoordinator:NSPersistentStoreCoordinator{
if !(_persistentStoreCoordinator != nil) {
let storeURL = self.applicationDocumentsDirectory.appendingPathComponent(storeName)
_persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
do{
//sqlite样式的存储
try _persistentStoreCoordinator!.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: self.databaseOptions())
}catch _ as NSError{
abort()
}
}
return _persistentStoreCoordinator!
}
最后是创建Context:
需要使用coordinator创建Context:
//context初始化
var managedObjectContext:NSManagedObjectContext{
//创建context,context需要coordinator
if Thread.isMainThread{
if !(_managedObjectContext != nil){
let coordinator = self.persistentStoreCoordinator
if coordinator != NSNull(){
//主队列的context
_managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
_managedObjectContext!.persistentStoreCoordinator = coordinator
}
return _managedObjectContext!
}
}else{
var threadContext:NSManagedObjectContext? = Thread.current.threadDictionary["NSManagedObjectContext"] as? NSManagedObjectContext
if threadContext == nil {
//非主队列的context
threadContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
//设置parent
threadContext!.parent = _managedObjectContext
//设置name
threadContext!.name = Thread.current.description
Thread.current.threadDictionary["NSManagedObjectContext"] = threadContext
NotificationCenter.default.addObserver(self, selector: #selector(CoreDataManager.contextWillSave(_:)), name: NSNotification.Name.NSManagedObjectContextWillSave, object: threadContext)
}else{
print("using old context")
}
return threadContext!
}
return _managedObjectContext!
}
对于CoreData中数据的处理,有删除和修改,添加,更新,查询等:
查询:
func executeFetchRequest(_ request:NSFetchRequest<NSFetchRequestResult>) -> Array<NSFetchRequestResult>? {
var results:Array<NSFetchRequestResult>?
self.managedObjectContext.performAndWait {
var fetchError:NSError?
do{
results = try self.managedObjectContext.fetch(request)
}catch let error as NSError{
fetchError = error
results = nil
}catch {
fatalError()
};
if let error = fetchError{
print("Warning!! \(error.description)")
}
}
return results
}
或者带回调的查询:
func executeFetchRequest(_ request:NSFetchRequest<NSFetchRequestResult>,completionHanlder:@escaping (_ results:Array<NSFetchRequestResult>?) -> Void) {
self.managedObjectContext.perform(){
var fetchError:NSError?
var results:Array<NSFetchRequestResult>?
do{
results = try self.managedObjectContext.fetch(request)
}catch let error as NSError{
fetchError = error
results = nil
}catch{
fatalError()
}
if let error = fetchError {
print("Warning!! \(error.description)")
}
completionHanlder(results)
}
}
保存数据:
func save() {
let context:NSManagedObjectContext = self.managedObjectContext
if context.hasChanges{
context.perform {
var saveError:NSError?
let saved:Bool
do{
try context.save()
saved = true
}catch let error as NSError{
saveError = error
saved = false
}catch {
fatalError()
};
if !saved{
if let error = saveError{
print("Warning!! Saving error \(error.description)")
}
}
if context.parent != nil{
context.parent!.performAndWait {
var saveError:NSError?
let saved:Bool
do{
try context.parent!.save()
saved = true
}catch let error as NSError{
saveError = error
saved = false
}catch {
fatalError()
}
if !saved{
if let error = saveError{
print("Warning!! Saving parent error \(error.description)")
}
}
}
}
}
}
}
context存储时:
func contextWillSave(_ notification:Notification) {
let context:NSManagedObjectContext! = notification.object as! NSManagedObjectContext
let insertedObjects:NSSet = context.insertedObjects as NSSet
if insertedObjects.count != 0 {
var obtainError:NSError?
do{
try context.obtainPermanentIDs(for: insertedObjects.allObjects as! [NSManagedObject])
}catch let error as NSError{
obtainError = error
}
if let error = obtainError{
print("Warnning!! obtain ids error \(error.description)")
}
}
}
删除某一个model的数据:
func deleteEntity(_ object:NSManagedObject) {
object.managedObjectContext?.delete(object)
}
func deleteTable<ResultType:NSFetchRequestResult>(request:NSFetchRequest<ResultType>,tableName:String) {
let managedObjectContext = self.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: tableName, in: managedObjectContext)
let request = NSFetchRequest<NSFetchRequestResult>()
request.includesPropertyValues = false
request.entity = entity
let items = self.executeFetchRequest(request)
if (items != nil && items!.count > 0){
for obj in items! {
let item = obj as! NSManagedObject
self.deleteEntity(item)
}
self.save()
}
}
以上是对CoreData的初始化,在具体到某一个Model的时候,需要再进行封装:
有数据转化(获取的数据转成对应的model)、获取数据、保存数据,添加数据,删除数据等;需要用到刚才初始化的CoreDataManager:
import Foundation
import CoreData
import SwiftyJSON
class ArticleDal: NSObject {
func addList(_ items:[AnyObject]) {
for po in items{
self.addArticle(po,save:false)
}
CoreDataManager.shared.save()
}
func addArticle(_ obj:AnyObject,save:Bool) {
let context = CoreDataManager.shared.managedObjectContext
let model = NSEntityDescription.entity(forEntityName: "Article", in: context)
let article = Article(entity: model!, insertInto: context)
if model != nil{
self.obj2ManagedObject(obj,article:article)
if save {
CoreDataManager.shared.save()
}
}
}
func deleteAll() {
CoreDataManager.shared.deleteTable(request: NSFetchRequest<Article>(), tableName: "Article")
}
func save() {
let context = CoreDataManager.shared.managedObjectContext
do{
try context.save()
}catch _{
}
}
func getList() -> [AnyObject]? {
let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Article")
let sort1 = NSSortDescriptor(key: "articleId", ascending: false)
request.fetchLimit = 30
request.sortDescriptors = [sort1]
request.resultType = .dictionaryResultType
let result = CoreDataManager.shared.executeFetchRequest(request)
return result
}
func obj2ManagedObject(_ obj:AnyObject,article:Article) {
var data = JSON(obj)
let articleId = data["articleId"].int64!
let title = data["title"].string!
let content = data["content"].string
let createDate = data["createDate"].int64!
let viewCount = data["viewCount"].int64!
let siteId = data["siteId"].int64!
let sourceName = data["sourceName"].string
let sourceUrl = data["sourceUrl"].string
let author = data["author"].string
let language = data["language"].string
let imageUrl = data["imageUrl"].string
article.articleId = articleId
article.title = title;
article.content = content;
article.createDate = createDate
article.siteId = siteId
article.sourceName = sourceName
article.viewCount = viewCount
article.sourceUrl = sourceUrl
article.author = author
article.language = language
article.imageUrl = imageUrl
}
}