Хранить изображение в Core Data в Swift - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь сохранить локальное изображение в моем приложении в базовой модели данных.Я создал сущность и создал атрибут для изображения.Но когда я запускаю приложение, оно вылетает с этой ошибкой, 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")
    }

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

В отличие от предыдущего ответа, изображения в Core Data можно хранить как UIImage.Хотя это не считается хорошей практикой, поскольку базы данных не предназначены для хранения файлов.Мы не используем основные данные для непосредственного хранения изображений, вместо этого мы используем путь к файлу, в котором хранятся данные изображений на вашем телефоне.

В любом случае, лучший метод, который я обнаружил при разработке побочного проекта, показан ниже

  1. Установите для CodeGen объекта значение Manual / None

  2. Выберите атрибут типа изображения и выберите преобразуемый в качестве типа

  3. Введите пользовательскийидентификатор класса как UIImage

  4. Перейдите в редактор и выберите Создать NSManagedObject Subclass

  5. Процесс создаст 2быстрые файлы в зависимости от количества ваших сущностей (у меня был только 1 сущность).Теперь выберите файл <EntityName> + CoreDataProperties.swift и import UIKit

Если при нажатии Перейти к определению для @NSManaged public var <attributeName: UIImage? вы можетечтобы получить UIImage определение ваша работа завершена.

Выполните действия над объектами так же, как вы, и вы сможете получить, сохранить, отредактировать атрибут изображения путем приведения вниз<EntityName>?.value(forKey: "<attributeName>") as? UIImage.

Мне пришлось использовать объект как тип NSManagedObject, и по какой-то причине он не мог получить доступ к изображению напрямую из созданного подкласса.

0 голосов
/ 13 июня 2018

Вы не можете сохранить UIImage непосредственно в Core Data.Вместо этого вам придется преобразовать изображение в NSData (как в «требуемый тип = 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...