iOS SwiftUI-2 Core Data資料庫使用


Posted by John on 2021-01-05

  1. 在創建專案的時候,將Use Core Data打勾

  2. 打勾後專案建立時,會在專案目錄下,出現xxxx.xcdatamodeld,xxxx是專案名字

  3. 幫Model建立資料,如下圖
    a. Add Entity
    b. 修改Entity名字
    c. 新增資料和資料形態

  4. Model處理完後,就可以直接拿來使用囉,使用的核心

     //需要取得NSManagedObjectContext
     let context = appDelegate.persistentContainer.viewContext
     //需要forEntityName,就是3.那張圖裡面數字 2 的名字,如下
     let coreDataName = "CameraInfoModel"
     NSEntityDescription.insertNewObject(forEntityName: coreDataName, into: context) as? CameraInfoModel
    
  5. 建立一個class架構來使用Core Data

     //1.初始化傳入使用的EntityName,還有NSManagedObjectContext
     class CoreDataBase {
         let coreDataName: String?
         let context: NSManagedObjectContext
         init(coreDataName: String?, context: NSManagedObjectContext) {
             self.coreDataName = coreDataName
             self.context = context
         }
         ...
     }
    
     //2.資料讀取,傳入NSPredicate條件篩選,以及如何排列資料和限制數量,為了可以彈性所以皆使用?
     func fetch(predicate: String?, sort: [[String: Bool]]?, limit:Int?) -> [CameraInfoModel]? {
         //確保已有選定了Entity的名字
         if let coreDataName = self.coreDataName {
             //選擇
             let request = NSFetchRequest<NSFetchRequestResult>(entityName: coreDataName)
             //條件篩選
             if let predicate = predicate {
                 request.predicate = NSPredicate(format: predicate)
             }
             //資料排列,可以有多個組合
             if let sort = sort {
                 var array: [NSSortDescriptor] = []
                 for sortCondition in sort {
                     for(key, value) in sortCondition {
                         array.append(NSSortDescriptor(key: key, ascending: value))
                     }
                 }
                 request.sortDescriptors = array
             }
             //設定長度限制
             if let limitNumber = limit {
                 request.fetchLimit = limitNumber
             }
             do {
                 //讀取資料
                 let results =
                     try context.fetch(request) as? [CameraInfoModel]
                 if let results = results {
                     //資料不為nil則回傳
                     return results
                 }
             } catch {
                 fatalError("\(error)")
             }
         }
         return nil
     }
    
     //3. 新增資料
     func insert(attributes: [[String: String]]) -> Bool {
         //確保已有選定了Entity的名字
         if let coreDataName = self.coreDataName {
             //取得要新增的資料
             let data = NSEntityDescription.insertNewObject(forEntityName: coreDataName, into: context) as? CameraInfoModel
             //如果有取得到才做
             if let data = data {
                 //傳入要設定的資料
                 for attribute in attributes {
                     for (key, value) in attribute {
                         //檢查資料型態
                         let type = data.entity.attributesByName[key]?.attributeType
                         if type == .integer16AttributeType
                             || type == .integer32AttributeType
                             || type == .integer64AttributeType {
                             //設定資料
                             data.setValue(Int(value), forKey: key)
                         } else if type == .doubleAttributeType
                                     || type == .floatAttributeType {
                             //設定資料
                             data.setValue(Double(value), forKey: key)
                         } else if type == .booleanAttributeType {
                             //設定資料
                             data.setValue(value == "true" ? true : false, forKey: key)
                         } else {
                             //設定資料
                             data.setValue(value, forKey: key)
                         }
                     }
                 }
                 do {
                     //設定完後將資料儲存
                     try context.save()
                     //設定完成返回成功
                     return true
                 } catch {
    
                 }
             }
         }
         return false
     }
    
     //4. 更新資料
     func update(predicate: String?, attritube: [String: String]) -> Bool {
         //讀取資料
         if let results = fetch(predicate: predicate, sort: nil, limit: nil) {
             //將讀取的資料做改變
             for result in results {
                 for(key, value) in attritube {
                     let type = result.entity.attributesByName[key]?.attributeType
                     if type == .integer16AttributeType
                         || type == .integer32AttributeType
                         || type == .integer64AttributeType {
                         result.setValue(Int(value), forKey: key)
                     } else if type == .doubleAttributeType
                                 || type == .floatAttributeType {
                         result.setValue(Double(value), forKey: key)
                     } else if type == .booleanAttributeType {
                         result.setValue(value == "true" ? true : false, forKey: key)
                     } else {
                         result.setValue(value, forKey: key)
                     }
                 }
             }
             do {
                 //儲存資料
                 try self.context.save()
                 //設定完成返回成功
                 return true
             } catch {
                 fatalError("\(error)")
             }
         }
         return false
     }
    
     //5. 刪除資料
     func delete(predicate: String?) -> Bool {
         //讀取資料
         if let results = fetch(predicate: predicate, sort: nil, limit: nil) {
             //將讀取的資料刪除
             for result in results {
                 context.delete(result)
             }
             do {
                 //儲存資料
                 try context.save()
                 //設定完成返回成功
                 return true
             } catch {
    
             }
         }
         return false
     }
    
  6. 引用5.建立好的class

     //取得AppDelegate
     let appDelegate = (UIApplication.shared.delegate as? AppDelegate)
     if let appDelegate = appDelegate {
         //取得NSManagedObjectContext
         let context = appDelegate.persistentContainer.viewContext
         //初始化CoreDataBase
         let coreDataBase = CoreDataBase(coreDataName: "CameraInfoModel", context: context)
    
         //插入資料
         var array: [[String: String]] = [[:]]
         array.append(["name": "John"])
         array.append(["ssid": "DIE12345321"])
         let successed = coreDataBase.insert(attributes: array)
    
         //讀取資料
         if let results = coreDataBase.fetch(predicate: nil, sort: [["name": true]], limit: nil) {
             for result in results {
                 print("result \(result.name), \(result.ssid)")
             }
         }
    
         //更新資料
         let successed = coreDataBase.update(predicate: nil, attritube: ["ssid": "12345"])
    
         //刪除資料
         let successed = coreDataBase.delete(predicate: nil)
    
         //條件選擇,讀取資料
         if let results = coreDataBase.fetch(predicate: "name = \"John\" || ssid = \"DIE12345321\"", sort: [["name": true]], limit: nil) {
             for result in results {
                 print("result \(result.name), \(result.ssid)")
             }
         }
     }
    

##iOS ##Swift #CoreData #程式語言 #程式設計 #資料庫 #Database







Related Posts

七天帶你初探AR世界-Day 7

七天帶你初探AR世界-Day 7

JavaScript 中的同步與非同步 & event loop

JavaScript 中的同步與非同步 & event loop

團隊的推進器 — 開放與學習

團隊的推進器 — 開放與學習


Comments