为CoreData封装一个简易的操作类

By | 2015年8月26日

前言

在创建一个项目时,如果选择了CoreData,那么会在AppDelegate类中为我们创建一些和CoreData相关的代码,我们把这些代码提取出来,稍作修改便可以得到一个适应我们自己项目的CoreData操作库。

我将CoreData操作库分为2个类,分别是底层的SCCoreData类,它是一个单例类,主要负责CoreData的上下文对象(NSManagedObjectContext)、持久化助理(NSPersistentStoreCoordinator)等对象的创建;另外一个是我们直接调用的SCCoreDataHelper类,提供了常用的增加、删除、查询、保存等静态方法的调用。

SCCoreData类

SCCoreData类的大部分代码来自Xcode在AppDelegate中为我们创建的代码,这里仅加上一个得到单例的方法。

import Foundation
import CoreData

public class SCCoreData{

    struct SCCoreDatsStruct {
        static var modelName:String = ""
        static var token:dispatch_once_t = 0
        static var instance:SCCoreData? = nil
    }

    /// 获取单例
    class func sharedInstance(#modelName:String)->SCCoreData{

        //只会运行一次
        dispatch_once(&SCCoreDatsStruct.token){

            SCCoreDatsStruct.instance = SCCoreData()
        }

        SCCoreDatsStruct.modelName = modelName

        return SCCoreDatsStruct.instance!
    }


    /// 数据库路径
    lazy var applicationDocumentsDirectory: NSURL = {
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count-1] as! NSURL
    }()

    /// 整个对象模型
    lazy var managedObjectModel: NSManagedObjectModel = {

        let name = SCCoreDatsStruct.modelName

        let modelURL = NSBundle.mainBundle().URLForResource(name, withExtension: "momd")!
        return NSManagedObjectModel(contentsOfURL: modelURL)!
    }()


    /// 持久化助理
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {

        var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

        let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("db.sqlite")

        var error: NSError? = nil

        var failureReason = "There was an error creating or loading the application's saved data."

        if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil
        {
            coordinator = nil
            var dict = [String: AnyObject]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReason
            dict[NSUnderlyingErrorKey] = error
            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
            NSLog("Unresolved error \(error), \(error!.userInfo)")
            abort()
        }

        return coordinator
        }()


    /// 对象管理上下文
    lazy var managedObjectContext: NSManagedObjectContext? = {
        let coordinator = self.persistentStoreCoordinator

        if coordinator == nil {
            return nil
        }
        var managedObjectContext = NSManagedObjectContext()
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()


    /// 最终保存数据
    func saveContext () {
        if let moc = self.managedObjectContext {
            var error: NSError? = nil
            if moc.hasChanges && !moc.save(&error) {
                NSLog("Unresolved error \(error), \(error!.userInfo)")
                abort()
            }
        }
    }
}

SCCoreDataHelper类

import Foundation
import CoreData

public class SCCoreDataHelper{


    //这里的Model参数要修改为xcdatamodeld的文件名
    static var coreDataInstance = SCCoreData.sharedInstance(modelName: "Model")

    static var coreDataContext = coreDataInstance.managedObjectContext


    /// 根据指定对象名称  获取NSManagedObject对象
    class func getManagedObject(objectName:String)->NSManagedObject?{

        var managedObject = NSEntityDescription.insertNewObjectForEntityForName(objectName, inManagedObjectContext: coreDataContext!) as? NSManagedObject

        return managedObject
    }

    /// 保存数据
    class func save(){
        coreDataInstance.saveContext()
    }

    /// 插入数据
    class func add(tableName:String,data:[String:AnyObject]){

        var object = getManagedObject(tableName)

        if let obj = object{

            for (key,value) in data{
                obj.setValue(value, forKey: key)
            }
        }
    }

    /// 删除一条数据
    class func delete(managedObject:NSManagedObject){
        coreDataContext?.deleteObject(managedObject)
    }

    /// 创建一个谓词对象,包含了过滤条件
    class func queryPredicate(whereString:String)->NSPredicate{
        return NSPredicate(format: whereString)
    }

    /// 创建一个查询请求对象
    class func queryRequest(tableName:String,whereString:String)->NSFetchRequest{

        var fetchRequest = NSFetchRequest(entityName: tableName)

        if  whereString != ""{
            let predicate = queryPredicate(whereString)
            fetchRequest.predicate = predicate
        }

        return  fetchRequest
    }

    /// 执行一个查询操作,返回包含查询结果的NSManagedObject数组
    class func query(tableName:String,whereString:String)->[NSManagedObject]? {

        let fetchRequest = queryRequest(tableName, whereString: whereString)
        return coreDataContext?.executeFetchRequest(fetchRequest, error: nil) as? [NSManagedObject]
    }

}

使用方法

//查询数据库中是否已经有Token数据了
let result = SCCoreDataHelper.query("Token", whereString: "")
//有数据,那就更新
if result?.count != 0{
    for obj in result!{
        obj.setValue(token, forKey: "access_token")
    }

}else{
    //没有数据,那就add

    let d = ["access_token":token!,"refresh_token": reftoken! , "expires_in": expiresin!,"uid":uid!]

    SCCoreDataHelper.add("Token", data: d.toDictionary())
}
SCCoreDataHelper.save()