将对象保存在核心数据中(字符串属性,双精度数组)

Posted

技术标签:

【中文标题】将对象保存在核心数据中(字符串属性,双精度数组)【英文标题】:Save Object in CoreData (Attributes with String, Double & Array) 【发布时间】:2018-04-05 12:09:59 【问题描述】:

我无法在 CoreData 中保存对象。它之前工作正常,但我将三个变量从字符串更改为字符串数组...图像、图像描述和属性 我有一个名为 CoreDataHandler 的文件,如下所示。

class CoreDataHandler: NSObject 
private class func getContext() -> NSManagedObjectContext 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    return appDelegate.persistentContainer.viewContext

class func saveObject(name: String, type: String, description: String, image: [String], imageDesc: [String], attrib: [String], rating: String, address: String, lat: Double, long: Double, annoName: String) -> Bool 
    //cost: String, openingTimes: String, pets: String, 
    let context = getContext()
    let entity = NSEntityDescription.entity(forEntityName: "CastleSave", in: context)
    let manageObject = NSManagedObject(entity: entity!, insertInto: context)

    manageObject.setValue(name, forKey: "name")
    manageObject.setValue(type, forKey: "type")
    manageObject.setValue(description, forKey: "desc")
    manageObject.setValue([image], forKey: "image")
    manageObject.setValue([imageDesc], forKey: "imageDesc")
    manageObject.setValue([attrib], forKey: "attrib")
    manageObject.setValue(rating, forKey: "rating")
    manageObject.setValue(address, forKey: "address")
    manageObject.setValue(lat, forKey: "lat")
    manageObject.setValue(long, forKey: "long")
    manageObject.setValue(annoName, forKey: "annoName")

    do 
        try context.save()
        return true
     catch 
        return false
    

我使用下面的代码保存为收藏夹

CoreDataHandler.saveObject(name: (txte?.name)!, type: (txte?.type)!, description: (txte?.description)!, image: (txte?.image)!, imageDesc: (txte?.imageDesc)!, attrib: (txte?.attrib)!, rating: (txte?.rating)!, address: (txte?.address)!, lat: (txte?.lat)!, long: (txte?.long)!, annoName: (txte?.annoName)!)

在我的数据模型中... 我之前将 image、imageDesc 和 attrib 的属性设置为 String。 我将其更改为 Transformable,并将属性 CustomClass 更改为 [String],但我正在努力了解如何正确保存它。

有人可以帮忙吗?

【问题讨论】:

您经常使用类似于(txte?.name)! 的模式,这可能会简化为txte!.name 究竟是什么问题,崩溃或没有保存或...? 您不能直接在CoreData 中保存array。查看可用的数据类型here。检索后使用join 函数和separate 从数组中创建一个字符串。 所以我将所有数据从 GeoJSON 文件加载到 MapView 中。然后,一旦我单击注释,它就会加载适当的数据。这就是 txte 的来源,它基本上是从以前的视图控制器中分离出来的对象。当我按下保存按钮(保存到 coredata)时,Xcode 完全崩溃,我必须重新打开 Xcode。我将图像保存为字符串。 不要将图像保存为字符串,而是将图像保存在documentDirectory 并将其路径保存到数据库中。 【参考方案1】:

这并不是第一个示例,但我无法理解您是从何处或如何创建此代码的。当核心数据以这里的方式使用时,帮助解决如此复杂的问题变得越来越困难。

当您创建模型时,您的应用应自动为您生成文件,这些文件可用于直接与核心数据进行通信。应该有与模型中命名相同的托管对象的子类。比如

let manageObject = NSManagedObject(entity: entity!, insertInto: context)

应该改为

let castleSave = NSManagedObject(entity: entity!, insertInto: context) as! CastleSave

你应该可以直接调用属性,比如castleSave.name = name

如果你有这个,你会看到你不能调用castleSave.image = [image],因为如果正确完成你的image属性是Data。所以你需要序列化这些东西。

所以看起来问题是如何将图像数组转换为数据。我猜JSONSerialization 加上base64 字符串编码应该这样做:

func dataFromImageArray(images: [UIImage]) -> Data? 
    let imageDataArray: [Data] = images.compactMap  UIImageJPEGRepresentation($0, 1.0) 
    let imageBase64Array: [String] = imageDataArray.compactMap  $0.base64EncodedString() 
    let jsonData: Data? = try? JSONSerialization.data(withJSONObject: imageBase64Array, options: [])
    return jsonData


func imageArrayFromData(data: Data) -> [UIImage] 
    guard let items = (try? JSONSerialization.jsonObject(with: data, options: [.allowFragments])) as? [String] else 
        return []
    

    let dataItems: [Data] = items.compactMap  Data(base64Encoded: $0) 
    let images: [UIImage] = dataItems.compactMap  UIImage(data: $0) 

    return images

可以对任何可转换为数据的对象数组进行非常相似的操作。

【讨论】:

以上是关于将对象保存在核心数据中(字符串属性,双精度数组)的主要内容,如果未能解决你的问题,请参考以下文章

无法将双精度的 NSArray 保存到文件 ios

核心数据保存日期错误

使用逗号时将字符串转换为双精度

JS:JSON的属性名必须要加双引号吗?

如何使用核心数据访问保存在不同视图控制器中的数组?

Java基础