最近开端学习Swift,想运用纯Swift完结一个本地事件薄APP,其中数据存储采用CoreData,下面记录CoreData在运用中的几个问题点,欢迎指导!!!

首要, 创立CoreData,过程就不细说了,这儿主要有两个问题 第一个就是挑选值类型的时分,如果要存储类似于字典、数组或许其他类型的时分,挑选Transformable类型,这个类型从字面意思来理解为可转化类型。挑选后,选中这条数据,如下图

Swift CoreData 使用及Transformable多类型存储
可以看到在Trasnformer这栏填上自己界说的类,这个类需求承继于ValueTransformer

下面贴上我的代码

@objc(SSLDictionaryModel)
final class SSLDictionaryModel: ValueTransformer {
  override func transformedValue(_ value: Any?) -> Any? {
    guard let dict = value as? NSDictionary else{
      return nil
    }
    do {
      if #available(iOS 11.0, *) {
        let data = try NSKeyedArchiver.archivedData(withRootObject:dict, requiringSecureCoding: true)
        return data
      } else {
        // Fallback on earlier versions
        return NSKeyedArchiver.archivedData(withRootObject:dict)
      }
    }catch{
      assertionFailure("Failed to transform 'NSDictionary' to 'Data'")
      return nil
    }
  }
  override func reverseTransformedValue(_ value: Any?) -> Any? {
    guard let data = value as? NSData else{return nil}
    do {
      if #available(iOS 11.0, *) {
        let dict = try NSKeyedUnarchiver.unarchivedObject(ofClass:NSDictionary.self, from:data as Data)
        return dict
      }else {
        guard let dict = NSKeyedUnarchiver.unarchiveObject(with: data as Data)else{
          return nil
        }
        return dict
      }
    }catch{
      assertionFailure("Failed to transform 'Data' to 'NSDictionary'")
      return nil
    }
  }
  override class func allowsReverseTransformation() -> Bool {
    return true
  }
  override class func transformedValueClass() -> AnyClass {
    return NSDictionary.self
  }
}

如果要转化其他类型,比方数组,则将NSDictionary改成NSArray,其他对应改就OK。

第二点就是在创立模型的时分需求挑选是系统隐性生成仍是手动的生成,系统默认是隐式生成模型类(Class definition),这时如果自己再手动的创立会出现文件抵触

Swift CoreData 使用及Transformable多类型存储
挑选后再在Xcode的Editor中挑选Create NSManagedObject Subclass 手动的创立模型

至此,数据库模型创立完结

下面是数据库的运用 创立数据库

func setupData(name: String){
    let url = Bundle.main.url(forResource: "SSLCoreData", withExtension: "momd")!
    guard let managedObjectModel = NSManagedObjectModel(contentsOf: url)else{
      fatalError("Manager object model could not be created.")
    }
    persisContext = NSPersistentContainer(name: name, managedObjectModel: managedObjectModel)
    persisContext?.loadPersistentStores(completionHandler: { storeDescription, error in
      if let err = error as NSError?{
        fatalError("Unresolved error\(err.userInfo)")
      }
    })
  }

数据查询

func requestFoodSettingData(_ page: Int = 0, result: @escaping(_ data: Array<SSLFoodListSettingModel>, _ status: Bool)->Void){
    if persisContext == nil{
      return
    }
    requestQueue.async { [weak self] in
      let fetchRequest = NSFetchRequest<SSLCoreSetting>(entityName: "SSLCoreSetting")
      fetchRequest.fetchLimit = 100;
      fetchRequest.fetchOffset = page;
      let entity = NSEntityDescription.entity(forEntityName: "SSLCoreSetting", in: (self?.persisContext!.viewContext)!)
      fetchRequest.entity = entity
      do{
        if let fetchedObject = try self?.persisContext?.viewContext.fetch(fetchRequest){
          var data : Array<SSLFoodListSettingModel> = []
          for foodSetting in fetchedObject{
            let foodSettingModel = SSLFoodListSettingModel()
            foodSettingModel.createTime = foodSetting.createTime
            foodSettingModel.tag = SSLFoodListType(rawValue: Int(foodSetting.tag))
            if (foodSetting.dataKeys != nil){
              foodSettingModel.dataKeys = foodSetting.dataKeys as? [String]
            }
            foodSettingModel.isUpdateKeys = foodSetting.isUpdateKeys
            data.append(foodSettingModel)
          }
          result(data, true)
        }
        else
        {
          result([],false)
        }
      }catch{
        result([],false)
      }
    }
  }

刺进数据

func reqeustInsertFoodSettingData(_ model: SSLFoodListSettingModel, result: @escaping(_ status: Bool)-> Void){
    requestQueue.async { [weak self] in
      if ((self?.persisContext) != nil){
        let settingModel : SSLCoreSetting = NSEntityDescription.insertNewObject(forEntityName: "SSLCoreSetting", into: (self?.persisContext!.viewContext)!) as! SSLCoreSetting
        settingModel.createTime = model.createTime
        settingModel.listId = model.listId
        settingModel.tag = Int16(model.tag?.rawValue ?? 0)
        if (model.dataKeys != nil){
          settingModel.dataKeys = model.dataKeys as NSObject?
        }
        settingModel.isUpdateKeys = model.isUpdateKeys
        do {
          try self?.persisContext?.viewContext.save()
          result(true)
        }catch{
          result(false)
        }
      }
      else
      {
        result(false)
      }
    }
  }

修正数据和删去数据和查询逻辑根本雷同,就不做演示了,贴上操作API

删去
self?.persisContext?.viewContext.delete(settingModel!)
修正
self?.persisContext?.viewContext.save()

至此,简略的CoreData存储根本都能实现了

因为APP比较简略,目前没做太多的封装和处理,如有问题,欢迎提出纠正,谢谢