【问题标题】:How to save Array to CoreData?如何将数组保存到 CoreData?
【发布时间】:2015-07-01 18:23:08
【问题描述】:

我需要将我的数组保存到 Core Data。

let array = [8, 17.7, 18, 21, 0, 0, 34]

该数组中的值和值的数量是可变的。

1.我在我的 NSManagedObject 类中声明什么?

class PBOStatistics: NSManagedObject, Equatable {
    @NSManaged var date: NSDate
    @NSManaged var average: NSNumber
    @NSManaged var historicAverage: NSNumber
    @NSManaged var total: NSNumber
    @NSManaged var historicTotal: NSNumber
    @NSManaged var ordersCount: NSNumber
    @NSManaged var historicOrdersCount: NSNumber
    @NSManaged var values: [Double]  //is it ok?

    @NSManaged var location: PBOLocation

}

2。我在 .xcdatamodel 中声明什么?

3.如何将其保存在我的实体中?(我使用 MagicalRecord)

let statistics = (PBOStatistics.MR_createInContext(context) as! PBOStatistics)
statistics.values = [8, 17.7, 18, 21, 0, 0, 34] //is it enough?

【问题讨论】:

  • 没有“应该”,数据库设计取决于您,例如就我而言,如果这被证明是在您的应用程序中存储这些数据的最有效方式,那么您最好使用日期或文本格式。
  • 那么在我的NSManagedObject: @NSManaged var values: [Double] 里面好吗?你能告诉我应该在.xcdatamodel 中使用什么类型来保存它吗?
  • 我可能说的不够清楚,你问的方式是关于个人喜好,没有真正的问题需要解决。如果您正在寻找使用一对多关系的任何方法,请添加您尝试过的内容以及遇到问题的位置的信息。如果您了解您提到的每个解决方案并正在寻找最有效的解决方案 - 请列出您的效率标准并描述用例。如果由于某种原因您在理解不同类型的关系时遇到困难或根本不想使用关系 - 直接说出来。
  • 我更新了问题
  • 现在这是一个不错的问题,我已经为你添加了一个 MagicalRecord 标签,不幸的是我在这方面没有经验,希望有经验的人能够从这一点上更好地帮助你。

标签: ios arrays swift core-data magicalrecord


【解决方案1】:

以下代码适用于我在 CoreData 中存储 JSON 数组

func saveLocation(model: [HomeModel],id: String){

    let newUser = NSEntityDescription.insertNewObject(forEntityName: "HomeLocationModel", into: context)

    do{
        var dictArray = [[String: Any]]()
        for i in 0..<model.count{
            let dict = model[i].dictionaryRepresentation()
            dictArray.append(dict)
        }
        let data = NSKeyedArchiver.archivedData(withRootObject: dictArray)
        newUser.setValue(data, forKey: "locations")
        newUser.setValue(id, forKey: "id")
        try context.save()
    }catch {
       print("failure")
    }

}

【讨论】:

    【解决方案2】:

    将实体属性类型设为“二进制数据”

    NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:TheArray];
    myEntity.arrayProperty = arrayData;
    [self saveContext]; //Self if we are in the model class
    

    将原始数组检索为:

    NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:anEntity.arrayProperty];
    

    就是这样。

    【讨论】:

      【解决方案3】:

      如果保持简单并将数组存储为字符串

      试试这个:

      // Array of Strings
      let array: [String] = ["red", "green", "blue"]
      let arrayAsString: String = array.description
      let stringAsData = arrayAsString.data(using: String.Encoding.utf16)
      let arrayBack: [String] = try! JSONDecoder().decode([String].self, from: stringAsData!)
      

      对于其他数据类型分别:

      // Set of Doubles
      let set: Set<Double> = [1, 2.0, 3]
      let setAsString: String = set.description
      let setStringAsData = setAsString.data(using: String.Encoding.utf16)
      let setBack: Set<Double> = try! JSONDecoder().decode(Set<Double>.self, from: setStringAsData!)
      

      【讨论】:

      • 您的解决方案节省了我很多时间
      • 我不知道为什么,但这些解决方案都不适合我。我尝试了将字符串数组的数据存储在 Core Data 中并检索它,然后将其解码为字符串数组的解决方案,但它仍然无法正常工作。有什么建议吗?
      • 这是一种相当粗略的做法——数据在数据库中无法索引,因为它被存储为 BLOB。读取/写入数据也有相当多的开销——例如,您不能使用集合的任何方法轻松进行更改。使用可转换是首选方式。
      • 不错!我还将添加以下内容作为一种可能性,这在某些情况下可能会起作用! var array = ["red", "green", "blue"] var arrayString = array.joined(separator: "%20") var arrayBack = arrayString.components(separatedBy: "%20")
      【解决方案4】:

      斯威夫特 3 由于我们在 Swift 3 中不再有实现文件,我们要做的就是转到 xcdatamodeld 文件,选择实体和所需的属性(在本例中称为值)。 将其设置为可转换并将其自定义类设置为[Double]。现在将其用作普通数组。

      【讨论】:

      • 是否可以将自定义类定义为 [[String: Any]] ?字典数组
      • 理论上应该可以接受,但是我没试过。
      • 您始终可以将 codegen 设置为 Manual/None 并编写自己的 Core Data 模型类。
      • 不错的方法,TIL
      • 另外,将NSSecureUnarchiveFromData 设置为Value Transformer(它被重命名为“Transformer”)。否则,您可能会收到此运行时警告:'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
      【解决方案5】:

      将数组转换为 NSData

      let appDelegate =
          UIApplication.sharedApplication().delegate as! AppDelegate
      let managedContext = appDelegate.managedObjectContext
      let entity =  NSEntityDescription.entityForName("Device",
                                                      inManagedObjectContext:managedContext)
      let device = NSManagedObject(entity: entity!,
                                   insertIntoManagedObjectContext: managedContext)
      let data = NSKeyedArchiver.archivedDataWithRootObject(Array)
      
      device.setValue(data, forKey: "dataOfArray")
      do {
          try managedContext.save()
          devices.append(device)
      } catch let error as NSError  {
          print("Could not save \(error), \(error.userInfo)")
      }
      

      将 NSData 转换为数组

      let appDelegate =
          UIApplication.sharedApplication().delegate as! AppDelegate
      let managedContext = appDelegate.managedObjectContext
      let fetchRequest = NSFetchRequest(entityName: "Device")
      
      do {
          let results =
              try managedContext.executeFetchRequest(fetchRequest)
      
          if results.count != 0 {
      
              for result in results {
      
                      let data = result.valueForKey("dataOfArray") as! NSData
                      let unarchiveObject = NSKeyedUnarchiver.unarchiveObjectWithData(data)
                      let arrayObject = unarchiveObject as AnyObject! as! [[String: String]]
                      Array = arrayObject
              }
      
          }
      
      } catch let error as NSError {
          print("Could not fetch \(error), \(error.userInfo)")
      }
      

      例如:https://github.com/kkvinokk/Event-Tracker

      【讨论】:

      • 使用 NSData 确实更有意义、更简单。
      • 如果你想给那个属性添加一个谓词,它可能不起作用。
      【解决方案6】:

      好的,我做了一些研究和测试。使用 Transformable 类型,解决方案很简单:

      1.我在我的 NSManagedObject 类中声明什么?

      @NSManaged var values: [NSNumber]  //[Double] also works
      

      2。我在 .xcdatamodel 中声明什么?

      Transformable 数据类型。

      3.如何将其保存在我的实体中?

      statistics!.values = [23, 45, 567.8, 123, 0, 0] //just this
      

      “您可以将 NSArray 或 NSDictionary 存储为可转换的属性。这将使用 NSCoding 将数组或字典序列化为 NSData 属性(并在访问时适当地反序列化)” - Source

      或者如果您想将其声明为二进制数据,请阅读此simple article

      【讨论】:

      • 也适用于[NSString] 用于字符串数组
      • 从核心数据中获取时是否可以添加谓词?
      • 在我的情况下,我正在尝试使用字符串数组,但它不起作用
      • 你将如何以 swift 3 方式做到这一点?
      • 看起来这不适用于 Swift 的未来版本:stackoverflow.com/questions/62589985/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2015-08-01
      • 2012-12-09
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多