我正在尝试将我的应用中的本地图像保存到核心数据模型中。我创建了实体并为图像创建了一个属性。但是,当我运行应用程序时,它会因此错误而崩溃,Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "image"; desired type = NSData; given type = UIImage; value = <UIImage:
我保存图像的代码是,
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Saloon", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(nameLbl.text, forKey: "name")
newUser.setValue(addressLbl.text, forKey: "address")
newUser.setValue(distanceLbl.text, forKey: "distance")
newUser.setValue(rating.text, forKey: "rating")
newUser.setValue(imageView.image, forKey: "image") as? UIImage
do {
try context.save()
print("saved")
} catch {
print("Failed saving")
}
这就是我提取图像的方式,
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Saloon")
//request.predicate = NSPredicate(format: "age = %@", "12")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "name") as! String)
let image: Data = data.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)
imageView2.image = decodedimage
name2Lbl.text = data.value(forKey: "name") as? String
address2Lbl.text = data.value(forKey: "address") as? String
distance2Lbl.text = data.value(forKey: "distance") as? String
rating2Lbl.text = data.value(forKey: "rating") as? String
}
} catch {
print("Failed")
}
答案 0 :(得分:0)
您无法直接在Core Data中保存UIImage。相反,您必须将图像转换为NSData
(如错误消息中的“desired type = NSData”)。这是UIImage
的扩展名:
extension UIImage {
func jpegData(withCompressionQuality quality: CGFloat) -> Data? {
return autoreleasepool(invoking: {() -> Data? in
return UIImageJPEGRepresentation(self, quality)
})
}
}
quality
是0.0到1.0之间的值,后者表示JPEG压缩图像的最高质量。 autoreleasepool
的使用有助于避免在使用UIImageJPEGRepresentation
时偶然发现的内存泄漏问题。
然后,您可以使用以下代码保存图像:
if let imageData = imageView.image .jpegData(withCompressionQuality: 1.0) {
newUser.setValue(imageData, forKey: "image")
}
顺便说一下,如果这是你需要的,你也可以转换为PNG而不是JPEG,这是无损的。使用UIImagePNGRepresentation
代替UIImageJPEGRepresentation
。
答案 1 :(得分:0)
与上一个答案不同,可以将图像作为UIImage存储在Core Data中。尽管这不被认为是一种好习惯,因为数据库并不用于存储文件。我们不使用核心数据直接存储图像,而是使用文件路径存储图像数据到手机上。
无论如何,下面展示了我在开发附带项目时发现的最佳方法
选择要为图像类型的属性,然后选择transformable作为其类型
转到编辑器,然后选择Create NSManagedObject Subclass
该流程将根据您的实体数创建2个swift文件(我只有1个实体)。现在,选择<EntityName> + CoreDataProperties.swift
文件和import UIKit
如果在@NSManaged public var <attributeName: UIImage?
上单击Jump to Definition,就可以登陆UIImage definition,那么您的工作就完成了。
对实体执行操作就像您将要进行的一样,您将可以通过向下广播<EntityName>?.value(forKey: "<attributeName>") as? UIImage
来获取,保存和编辑图像属性。
我不得不将实体用作NSManagedObject
类型,由于某种原因,我无法直接从创建的子类访问图像。