日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Swift实现CoreData存储数据

發(fā)布時(shí)間:2025/4/16 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Swift实现CoreData存储数据 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前寫過一篇介紹iOS數(shù)據(jù)存儲(chǔ)方法的文章,包含:FMDB,SQLite3 ,Core Data,Plist,偏好設(shè)置,歸檔。 鏈接:www.jianshu.com/p/e88880be7…

本文則是介紹Swift中CoreData的基本使用。
文中示例代碼GitHub地址:Demo

目錄

一、 圖形化創(chuàng)建模型
二、 手動(dòng)創(chuàng)建模型并實(shí)現(xiàn)AppDelegate中的代碼
三、 創(chuàng)建并實(shí)現(xiàn)CoreDataManager

一、圖形化創(chuàng)建模型(這一小節(jié)的內(nèi)容我的另一篇文中也有,如已經(jīng)熟悉,或想要直接手動(dòng)創(chuàng)建模型,可以直接看第二小節(jié)正式進(jìn)入Swift)

創(chuàng)建項(xiàng)目的時(shí)候,勾選下圖中的Use Core Data選項(xiàng),工程中會(huì)自動(dòng)創(chuàng)建一個(gè)數(shù)據(jù)模型文件。當(dāng)然,你也可以在開發(fā)中自己手動(dòng)創(chuàng)建。

下圖就是自動(dòng)創(chuàng)建出來的文件

如果沒有勾選,也可以在這里手動(dòng)創(chuàng)建。

點(diǎn)擊Add Entity之后,相當(dāng)一張數(shù)據(jù)表。表的名稱自己在上方定義,注意首字母要大寫。 在界面中還可以為數(shù)據(jù)實(shí)體添加屬性和關(guān)聯(lián)屬性。

Core Data屬性支持的數(shù)據(jù)類型如下

編譯之后,Xcode會(huì)自動(dòng)生成Person的實(shí)體代碼文件,并且文件不會(huì)顯示在工程中,如果下圖中右側(cè)Codegen選擇Manual/None,則Xcode就不會(huì)自動(dòng)生成代碼,我們可以自己手動(dòng)生成。

  • 手動(dòng)生成實(shí)體類代碼,選中CoreDataTest.xcdatamodeld文件,然后在Mac菜單欄中選擇Editor,如下圖所示。一路Next就可以了。
  • 如果沒有選擇Manual/None,依然進(jìn)行手動(dòng)創(chuàng)建的話,則會(huì)與系統(tǒng)自動(dòng)創(chuàng)建的文件發(fā)生沖突,這點(diǎn)需要注意。
  • 你也可以不要選擇Manual/None,直接使用系統(tǒng)創(chuàng)建好的NSManagedObject,同樣會(huì)有4個(gè)文件,只是在工程中是看不到的。

Swift中手動(dòng)創(chuàng)建出來的是這樣2個(gè)文件

還要注意編程語言的選擇,Swift或OC

二、手動(dòng)創(chuàng)建模型并實(shí)現(xiàn)AppDelegate中的代碼

講道理,這一節(jié)應(yīng)該是Core Data堆棧的介紹與使用,不過由于之前的文章中已經(jīng)有了,這里就不啰嗦了,我們直接上圖和代碼。

  • 如下圖所示,創(chuàng)建模型,我這里直接創(chuàng)建一個(gè)命名為Model的模型。

  • 創(chuàng)建Person表,兩個(gè)屬性name和age,注意右側(cè)的Codegen我們這里選擇Class Definition,然后直接Command+B編譯代碼,Xcode會(huì)自動(dòng)幫我們生成Person+CoreDataClass.swift和Person+CoreDataProperties.swift文件

  • 配置AppDelegate中的代碼,首先導(dǎo)入CoreData頭文件,然后懶加載NSManagedObjectModel
  • 注意modelURL中填寫的是模型文件的名字,并且后綴填寫momd

    import CoreDatalazy var managedObjectModel: NSManagedObjectModel = {let modelURL = Bundle.main.url(forResource: "Model", withExtension: "momd")let managedObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!)return managedObjectModel!}() 復(fù)制代碼
  • 懶加載持久化存儲(chǔ)協(xié)調(diào)器NSPersistentStoreCoordinator
    • sqliteURL是sqlite文件的路徑
    • documentDir是后面加載好了的Document路徑
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {let persistentStoreCoordinator = NSPersistentStoreCoordinator.init(managedObjectModel: managedObjectModel)let sqliteURL = documentDir.appendingPathComponent("Model.sqlite")let options = [NSMigratePersistentStoresAutomaticallyOption : true, NSInferMappingModelAutomaticallyOption : true]var failureReason = "There was an error creating or loading the application's saved data."do {try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: sqliteURL, options: options)} catch {// Report any error we got.var dict = [String: Any]()dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as Any?dict[NSLocalizedFailureReasonErrorKey] = failureReason as Any?dict[NSUnderlyingErrorKey] = error as NSErrorlet wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 6666, userInfo: dict)print("Unresolved error \(wrappedError), \(wrappedError.userInfo)")abort()}return persistentStoreCoordinator}()lazy var documentDir: URL = {let documentDir = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).firstreturn documentDir!}() 復(fù)制代碼
  • 懶加載NSManagedObjectContext
  • lazy var context: NSManagedObjectContext = {let context = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)context.persistentStoreCoordinator = persistentStoreCoordinatorreturn context}() 復(fù)制代碼

    三、創(chuàng)建并實(shí)現(xiàn)CoreDataManager

    我一般是把數(shù)據(jù)存儲(chǔ)方法封裝到一個(gè)CoreDataManager中,這樣在以后的使用中比較方便。當(dāng)然,你也可以根據(jù)自己的需求靈活運(yùn)用。

  • 創(chuàng)建一個(gè)繼承自NSObject的CoreDataManager.swfit文件,并且import CoreData

  • 實(shí)現(xiàn)CoreDataManager的單例,并且拿到AppDelegate中剛才懶加載的NSManagedObjectContext

  • swift中創(chuàng)建單例比較方便,直接static let shared = CoreDataManager()

    // 單例static let shared = CoreDataManager()// 拿到AppDelegate中創(chuàng)建好了的NSManagedObjectContextlazy var context: NSManagedObjectContext = {let context = ((UIApplication.shared.delegate) as! AppDelegate).contextreturn context}() 復(fù)制代碼
  • 實(shí)現(xiàn)更新數(shù)據(jù)的方法
  • 除了查詢數(shù)據(jù),其余對(duì)數(shù)據(jù)進(jìn)行增刪改的時(shí)候,都別忘記調(diào)用這個(gè)方法,只有這個(gè)方法執(zhí)行ok,才算增刪改完成。

    // 更新數(shù)據(jù)private func saveContext() {do {try context.save()} catch {let nserror = error as NSErrorfatalError("Unresolved error \(nserror), \(nserror.userInfo)")}} 復(fù)制代碼
  • 增加數(shù)據(jù)(保存數(shù)據(jù))
    • 首先運(yùn)用NSEntityDescription創(chuàng)建出person
    • 然后為person賦值,最終調(diào)用saveContext()方法保存數(shù)據(jù)
    // 增加數(shù)據(jù)func savePersonWith(name: String, age: Int16) {let person = NSEntityDescription.insertNewObject(forEntityName: "Person", into: context) as! Personperson.name = nameperson.age = agesaveContext()} 復(fù)制代碼
  • 獲取所有數(shù)據(jù)
    • 如果是通過系統(tǒng)自動(dòng)生成的CoreData文件,Person會(huì)自帶一個(gè)fetchRequest()的方法,我們可以直接通過Person.fetchRequest()的方式拿到person的NSFetchRequest對(duì)象
    • 然后通過context的fetch(fetchRequest)方法拿到數(shù)據(jù)數(shù)組
    // 獲取所有數(shù)據(jù)func getAllPerson() -> [Person] {let fetchRequest: NSFetchRequest = Person.fetchRequest()do {let result = try context.fetch(fetchRequest)return result} catch {fatalError();}} 復(fù)制代碼
  • 獲取特定條件的數(shù)據(jù)
    • 可以利用NSPredicate來過濾出符合一定條件的數(shù)據(jù)
    • 而NSFetchRequest中有predicate這樣一個(gè)屬性
    // 根據(jù)姓名獲取數(shù)據(jù)func getPersonWith(name: String) -> [Person] {let fetchRequest: NSFetchRequest = Person.fetchRequest()fetchRequest.predicate = NSPredicate(format: "name == %@", name)do {let result: [Person] = try context.fetch(fetchRequest)return result} catch {fatalError();}} 復(fù)制代碼
  • 修改數(shù)據(jù)
    • 首先獲取到想要修改的數(shù)據(jù)
    • 然后循環(huán)修改就可以了
    • 最后別忘記save
    // 根據(jù)姓名修改數(shù)據(jù)func changePersonWith(name: String, newName: String, newAge: Int16) {let fetchRequest: NSFetchRequest = Person.fetchRequest()fetchRequest.predicate = NSPredicate(format: "name == %@", name)do {// 拿到符合條件的所有數(shù)據(jù)let result = try context.fetch(fetchRequest)for person in result {// 循環(huán)修改person.name = newNameperson.age = newAge}} catch {fatalError();}saveContext()} 復(fù)制代碼
  • 根據(jù)條件刪除數(shù)據(jù)
    • 與修改數(shù)據(jù)一樣,首先拿到符合刪除條件的數(shù)據(jù)
    • 循環(huán)調(diào)用context的delete()方法就可以了
    • 最后別忘記save
    // 根據(jù)姓名刪除數(shù)據(jù)func deleteWith(name: String) {let fetchRequest: NSFetchRequest = Person.fetchRequest()fetchRequest.predicate = NSPredicate(format: "name == %@", name)do {let result = try context.fetch(fetchRequest)for person in result {context.delete(person)}} catch {fatalError();}saveContext()} 復(fù)制代碼
  • 刪除所有數(shù)據(jù)
    • 獲取所有數(shù)據(jù)
    • 循環(huán)刪除
    • save
    // 刪除所有數(shù)據(jù)func deleteAllPerson() {// 這里直接調(diào)用上面獲取所有數(shù)據(jù)的方法let result = getAllPerson()// 循環(huán)刪除所有數(shù)據(jù)for person in result {context.delete(person)}saveContext()} 復(fù)制代碼

    后記

    本文運(yùn)用一個(gè)簡單的示例來說明swift中如何使用CoreData,更多用法或注意事項(xiàng)就不一一列舉了。

    本文Demo:github.com/remember17/…
    作者GitHub:github.com/remember17

    總結(jié)

    以上是生活随笔為你收集整理的Swift实现CoreData存储数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。