Swift iOS : Core Data

## javascript

Core Data是官方对Sqlite访问的封装框架。使用它的好处是:java

  1. 不须要本身引入Sqlite动态库和建立桥接文件
  2. 不须要使用SQL语言便可访问Sqlite

使用它的首要需求是引入它,像是这样:数据库

import CoreData复制代码

依然假设咱们的问题是存储todo项目,字段为id、item,但愿建立数据库、建立表、插入数据、查询数据一鼓作气,代码以下:app

import UIKit
    import CoreData

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        var context :NSManagedObjectContext!
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            let dbname = "foo.bar"
            // section : model
            let model = NSManagedObjectModel()
            let entity = NSEntityDescription()
            entity.name = "todo"
            var properties = Array<NSAttributeDescription>()
            let idAttr = NSAttributeDescription()
            idAttr.name = "id"
            idAttr.attributeType = .integer64AttributeType
            idAttr.isOptional = false
            idAttr.isIndexed = true
            properties.append(idAttr)
            let itemAttr = NSAttributeDescription()
            itemAttr.name = "item"
            itemAttr.attributeType = .stringAttributeType
            itemAttr.isOptional = false
            itemAttr.isIndexed = true
            properties.append(itemAttr)
            entity.properties = properties
            model.entities = [entity]

            // section : coordinator
            let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
            let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
            let docURL = urls[urls.count-1]
            let url = docURL.appendingPathComponent(dbname)

            do {
                try FileManager.default.removeItem(at: url)
            } catch _ {
            }
            do {
                try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
            } catch {
                print("caught: \(error)")
                abort()
            }
            //section : context
            context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
            context.persistentStoreCoordinator = coordinator
            // section : app code

            let todos = [
                (item: "Item 1",id:1),
                (item: "Item 2" ,id:2),
                (item: "Item 3",id:3)
            ]
            for todo in todos {
                let a =  NSEntityDescription.insertNewObject(forEntityName: "todo", into: context)
                a.setValue(todo.item, forKey:"item")
                a.setValue(todo.id, forKey:"id")
            }
            do {
                try context.save()
            } catch _ {
            }
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName:"todo")
            //        fetchRequest.predicate = NSPredicate(format: "notificationId = 13")

            do {
                let list = try context.fetch(fetchRequest) as? [NSManagedObject]
                print(list!.count)
                for zoo in list! {
                    print(zoo.value(forKey: "item")!,zoo.value(forKey: "id")!)
                }
            } catch let error as NSError {
                // failure
                print("Fetch failed: \(error.localizedDescription)")
            }
            window?.rootViewController  = UIViewController()
            return true
        }
        func applicationWillTerminate(_ application: UIApplication) {
            if context.hasChanges {
                do {
                    try context.save()
                } catch {
                    print("caught: \(error)")
                    abort()
                }
            }
        }
    }复制代码

完成要求的一系列的动做的过程当中,首先咱们来看建立数据库的模型,也就是标注为:框架

// section : model复制代码

开始的代码,它使用了以下的类:fetch

  1. NSManagedObjectModel
  2. NSEntityDescription
  3. NSAttributeDescription

既然是对Sqlite的封装,那么这些类显然分别对应于数据库、表、字段的。因此尽管代码看起来有些冗长,意图却是比较明显的。它们等同于建立这样的表:url

表名:todo
    表字段清单:
        名字  类型 可选 索引
        id   int64 否  是
        item string否  是复制代码

此处的代码只是建立了一个内存中的模型,真正的建立使用了NSPersistentStoreCoordinator,在标注为:spa

// section : coordinator复制代码

开始的代码中进行。NSPersistentStoreCoordinator用来把模型和真实的存储关联起来。NSPersistentStoreCoordinator的物理存储使用了Sqlite(NSSQLiteStoreType),可是也能够使用两位两种存储,分别为code

// public let NSBinaryStoreType: String
// public let NSInMemoryStoreType: Stringorm

代码中对FileManager的引用的目的就是在文件存储中关联一个文件,若是存在就会删除它。接下来的NSManaged​Object​Context能够调用它的save()方法,把当前上下文的数据存储起来,也能够使用fetch方法,经过NSFetchRequest指定表名和条件来查询数据。若是须要插入数据,则须要使用NSEntityDescription的insertNewObject()方法。

这只是一个案例,真正的应用有可能正在编辑数据时,App被退出,那么数据将不能被保存。若是须要在退出前保存的话,须要在:

func applicationWillTerminate(_ application: UIApplication)     复制代码

检测变化,并调用NSManaged​Object​Context.save()来保存数据。

做者

刘传君。建立过产品,创过业。好读书,求甚解。能够经过1000copy#gmail.com联系到我

出品

Vue.js小书 www.ituring.com.cn/book/1956

相关文章
相关标签/搜索