Swift 3 - 将图像保存到 Core Data
Swift 3 - Saving images to Core Data
出于某种原因,我不知道如何将图像保存到核心数据并再次获取它们。我有一种感觉,这与我的类型有关,但请看一下:
我从对服务器的 api 调用中获取数据。它 returns 一个 base64 字符串。
这是我获取数据的地方:
updateAccessTokenOnly(newAccessToken: aToken!)
saveImageToDB(brandName: imageBrandName, image: data! )
这里我将它保存到我的数据库中:
func saveImageToDB(brandName: String, image: Data) {
dropImages(){tableDropped in
let managedContext = getContext()
let entity = NSEntityDescription.entity(forEntityName: "CoffeeShopImage", in: managedContext)!
let CSI = NSManagedObject(entity: entity, insertInto: managedContext)
CSI.setValue(image, forKey: "image")
CSI.setValue(brandName, forKey: "brandName")
do {
try managedContext.save()
print("saved!")
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
然后获取它:
func getImageFromDB(callback: @escaping (_ image: UIImage)-> ()) {
let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "CoffeeShopImage")
do {
let searchResults = try getContext().fetch(fetchRequest)
for images in searchResults {
print("vi når her ned i get image")
if (images.value(forKey: "brandName")! as! String == "Baresso"){
print(images.value(forKey: "brandName")! as! String)
let image: Data = images.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)
callback(decodedimage!)
}
}
} catch {
print("Error with request: \(error)")
}
}
完整错误日志:
https://docs.google.com/document/d/1gSXE64Sxtzo81eBSjv4bnBjBnnmG4MX2tuvNtnuJDIM/edit?usp=sharing
希望有人能提供帮助。提前致谢!
已更新
所以我卸载了应用程序,然后上面的代码就起作用了。但是图片是蓝色的? (是的,我检查过从数据库发送的图片是正确的)。
有什么解决办法吗?
替换
let image: Data = images.value(forKey: "image")! as! Data
let dataDecoded : Data = Data(base64Encoded: image, options: [])!
let decodedimage = UIImage(data: dataDecoded)
和
let image: Data = images.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)
Base64 是一种将数据转换为字符串的方法。没有理由在这里使用它。您已经拥有数据库中的数据,您只想将其转换为 UIImage。
也改
let image = data?.base64EncodedData()
saveImageToDB(brandName: imageBrandName, image: image!)
到
saveImageToDB(brandName: imageBrandName, image: data!)
base64EncodedData
正在将图像数据中的数据转换为 utf-8 编码的基于 64 位编码的字符串。没有理由这样做。
您应该从服务器获取 base64 编码的字符串,将其转换为数据,然后您就再也不需要 base64 了。读取 data 并将其写入数据库,读取后将其转换为 UIImage。 Base64 是一种传输数据的编码方法。如果您不与服务器通信,则没有理由使用 base64。
在 Jon Rose 建议的更正之后,我只需要添加
.withRenderingMode(.alwaysOriginal)
到我展示图片和代码有效的地方。
正在保存图像:
guard let managedObjectContext = managedObjectContext else { return }
// Create User
let user = User(context: managedObjectContext)
// Configure User
user.name = "name"
user.about = "about"
user.address = "Address"
user.age = 30
if let img = UIImage(named: "dog.png") {
let data = img.pngData() as NSData?
user.image = data
}
正在获取图像:
// Create Fetch Request
let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
// Configure Fetch Request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let users = try! managedContext.fetch(fetchRequest)
let user: User = users.first as! User
if let imageData = user?.image {
imgView.image = UIImage(data: imageData as Data)
}
出于某种原因,我不知道如何将图像保存到核心数据并再次获取它们。我有一种感觉,这与我的类型有关,但请看一下:
我从对服务器的 api 调用中获取数据。它 returns 一个 base64 字符串。 这是我获取数据的地方:
updateAccessTokenOnly(newAccessToken: aToken!)
saveImageToDB(brandName: imageBrandName, image: data! )
这里我将它保存到我的数据库中:
func saveImageToDB(brandName: String, image: Data) {
dropImages(){tableDropped in
let managedContext = getContext()
let entity = NSEntityDescription.entity(forEntityName: "CoffeeShopImage", in: managedContext)!
let CSI = NSManagedObject(entity: entity, insertInto: managedContext)
CSI.setValue(image, forKey: "image")
CSI.setValue(brandName, forKey: "brandName")
do {
try managedContext.save()
print("saved!")
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
然后获取它:
func getImageFromDB(callback: @escaping (_ image: UIImage)-> ()) {
let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "CoffeeShopImage")
do {
let searchResults = try getContext().fetch(fetchRequest)
for images in searchResults {
print("vi når her ned i get image")
if (images.value(forKey: "brandName")! as! String == "Baresso"){
print(images.value(forKey: "brandName")! as! String)
let image: Data = images.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)
callback(decodedimage!)
}
}
} catch {
print("Error with request: \(error)")
}
}
完整错误日志:
https://docs.google.com/document/d/1gSXE64Sxtzo81eBSjv4bnBjBnnmG4MX2tuvNtnuJDIM/edit?usp=sharing
希望有人能提供帮助。提前致谢!
已更新
所以我卸载了应用程序,然后上面的代码就起作用了。但是图片是蓝色的? (是的,我检查过从数据库发送的图片是正确的)。
有什么解决办法吗?
替换
let image: Data = images.value(forKey: "image")! as! Data
let dataDecoded : Data = Data(base64Encoded: image, options: [])!
let decodedimage = UIImage(data: dataDecoded)
和
let image: Data = images.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)
Base64 是一种将数据转换为字符串的方法。没有理由在这里使用它。您已经拥有数据库中的数据,您只想将其转换为 UIImage。
也改
let image = data?.base64EncodedData()
saveImageToDB(brandName: imageBrandName, image: image!)
到
saveImageToDB(brandName: imageBrandName, image: data!)
base64EncodedData
正在将图像数据中的数据转换为 utf-8 编码的基于 64 位编码的字符串。没有理由这样做。
您应该从服务器获取 base64 编码的字符串,将其转换为数据,然后您就再也不需要 base64 了。读取 data 并将其写入数据库,读取后将其转换为 UIImage。 Base64 是一种传输数据的编码方法。如果您不与服务器通信,则没有理由使用 base64。
在 Jon Rose 建议的更正之后,我只需要添加
.withRenderingMode(.alwaysOriginal)
到我展示图片和代码有效的地方。
正在保存图像:
guard let managedObjectContext = managedObjectContext else { return }
// Create User
let user = User(context: managedObjectContext)
// Configure User
user.name = "name"
user.about = "about"
user.address = "Address"
user.age = 30
if let img = UIImage(named: "dog.png") {
let data = img.pngData() as NSData?
user.image = data
}
正在获取图像:
// Create Fetch Request
let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
// Configure Fetch Request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let users = try! managedContext.fetch(fetchRequest)
let user: User = users.first as! User
if let imageData = user?.image {
imgView.image = UIImage(data: imageData as Data)
}