Загрузить массив изображений в coredata

#ios #swift #core-data

#iOS #swift #core-данные

Вопрос:

Когда мне нужно было загрузить только одно изображение в coredata, у меня был только один объект, содержащий поле изображения,

Затем, когда мне понадобилось загрузить несколько изображений, я создал другой объект под названием images с полями image и id, поле id также присутствует в ресторанах,

Теперь, если пользователь хочет использовать несколько изображений ресторанов, я использую opalimagepicker для выбора нескольких изображений, а затем получаю обратно массив var arrayOfImages = [UIImage]()

Для одного изображения код был очень простым, я просто отображаю изображение в UIImageView, а затем использую его для загрузки в core data, как показано ниже

 if let restaurantImage = cell5.imageToUpload.image {
          restaurant.image = restaurantImage.pngData()
        }
  

Но теперь я хочу, чтобы несколько изображений хранились в объекте image, причем каждое изображение соответствовало одному и тому же идентификатору, то есть идентификатору пользователя, как показано ниже

image1 — abc

image2 — abc

Итак, опять же, я знаю, как загрузить одно изображение в одной модели объекта, но как загрузить массив изображений в модели с несколькими объектами

Но я не знаю, как это сделать с помощью coredata, может ли кто-нибудь указать мне полезный способ решить эту проблему, спасибо, моя модель отношений прилагается

Также в сущности «Рестораны» все еще есть поле изображения, как это настроить?

введите описание изображения здесь

ОБНОВИТЕ — таким образом, я могу сохранить массив изображений в объекте coredata restaurant, используя это. используя руководство @danielson

 for image in arrayOfImages {
          print("saved")
          restaurant.image = image.pngData()
        }
  

Но, как и в другой базе данных, я не могу использовать оператор select, чтобы увидеть, как были сохранены данные, у меня нет никакого способа узнать, как именно это было сделано,

также, как я могу извлечь, скажем, второе изображение из массива, в настоящее время, поскольку есть только одно изображение, я делаю это, это для извлечения данных из core data и их отображения, но как я теперь показываю определенное изображение из массива?

 if let restaurantImage = restaurant.image {
                     cell.restaurantMiniImage.image = UIImage(data: restaurantImage as Data)
                   }
  

Обновить

 import Foundation
import CoreData


extension Restaurant {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Restaurant> {
        return NSFetchRequest<Restaurant>(entityName: "Restaurant")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var image: Data?
    @NSManaged public var isVisited: Bool
    @NSManaged public var location: String?
    @NSManaged public var name: String?
    @NSManaged public var phone: String?
    @NSManaged public var rating: String?
    @NSManaged public var summary: String?
    @NSManaged public var type: String?
    @NSManaged public var images: NSSet?

}

// MARK: Generated accessors for images
extension Restaurant {

    @objc(addImagesObject:)
    @NSManaged public func addToImages(_ value: Images)

    @objc(removeImagesObject:)
    @NSManaged public func removeFromImages(_ value: Images)

    @objc(addImages:)
    @NSManaged public func addToImages(_ values: NSSet)

    @objc(removeImages:)
    @NSManaged public func removeFromImages(_ values: NSSet)

}





import Foundation
import CoreData


extension Images {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Images> {
        return NSFetchRequest<Images>(entityName: "Images")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var image: Data?
    @NSManaged public var origin: Restaurant?

}






 var arrayOfImages = [UIImage]()
    
    func getAssetThumbnail(assets: [PHAsset]) -> [UIImage] {
       
        for asset in assets {
            let manager = PHImageManager.default()
            let option = PHImageRequestOptions()
            var image = UIImage()
            option.isSynchronous = true
            manager.requestImage(for: asset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
                image = result!
                self.arrayOfImages.append(image)
            })
        }
        return arrayOfImages
    }
    
    
  

Комментарии:

1. Сработает ли для вас установление отношения «ко многим»? Таким образом, вы могли бы сохранить несколько изображений, которые имеют одинаковое происхождение из ресторана.

2. @aswath — это один ко многим, но я не знаю запроса coredata, чтобы иметь возможность вставлять изображения в объект image, который будет соответствовать идентификатору пользователя из ресторана

3. @JoakimDanielson — спасибо, поскольку я новичок в coredata, в итоге я использовал опцию ClassDefinition codegen вместо manual, поэтому я не получил класс Restaurant в своем навигаторе, но когда теперь я пытаюсь использовать код и опцию manual, я получаю ошибку каждый раз, когда я использовал ключевое слово Restaurant, используемое для доступа к этому объекту, как я могу продолжить?

Ответ №1:

У вашего Restaurant класса будет функция addToImages , которую вы сможете использовать. Итак, что-то вроде этого должно сработать

Создайте пользовательский метод инициализации для Images (который действительно должен иметь имя Image ), чтобы упростить остальную часть кода

 extension Images {
     convenience init(context: NSManagedObjectContext, image: UIImage) {
          self.init(context: context)
          self.id = UUID()
          self.image = image.pngData()
     }
}
  

и затем

 var arrayOfImages = [UIImage]()
    
for image in arrayOfImages {
    restaurant.addToImages(Images(context: moc, image: image))
}
  

Или все сразу

 restaurant.addToImages(Set(arrayOfImages.map { Images(context: moc, image: $0 })) 
  

В приведенных выше примерах кода moc является экземпляром NSManagedObjectContext .

Чтобы получить доступ к изображениям, вы можете прочитать images атрибут Restaurant , например, вот так, чтобы получить массив UIImage

 let imageArray = restaurant.images.map { UIImage(data: $0.image as Data) }
  

Что касается image атрибута в Restaurant : Вы можете просто удалить любые атрибуты в базовой модели данных, которые больше не используются

Комментарии:

1. спасибо, итак, как будет использоваться объект images, будут ли данные для изображения автоматически вводиться в него, а также как я смогу извлекать эти изображения? я ничего не знаю о coredata, поэтому спрашиваю

2. итак, теперь, когда я могу сохранить все изображения, в настоящее время я использую этот код для отображения изображения из core data — если пусть restaurantImage = restaurant.image { cell.restaurantMiniImage.image = UIImage(данные: restaurantImage как данные)} — но предположим, я пытаюсь отобразить второе изображение в массиве и использую restaurant.image [1], оно выдает ошибку, что я делаю не так, спасибо

3. Итак, теперь, когда я сохранил данные, используя for image в arrayOfImages { print («сохраненный») restaurant.image = image.pngData() } , мне было интересно, как мне извлечь это, чтобы иметь возможность получить доступ к определенному изображению из массива, если изображения

4. Вы можете получить доступ к изображениям, используя images атрибут в классе Restaurant, который возвращает набор Images .

5. Йоаким Дэниелсон, спасибо, но я запускал ваш код, теперь я компилирую классы вручную, но я продолжаю получать ошибку — Нет точных совпадений при вызове метода экземпляра ‘addToImages’, это функция, которую я получаю в своем классе — @objc(addImages:) @NSManaged public func addToImages(_ values: NSSet)