在建立了.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
}
}
複製程式碼