0

My swift code below saves 3 images. What I want to do is overwrite iamgedata2 is func press. Imagedata2 should be replaced with Gwen. So the order should be Gwen Gwen Gwen instead of Gwen gwen2 Gwen. I don't know what really to put in func press to achieve this goal.

import UIKit; import CoreData

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .orange
        let gwen = UIImage(named: "blank")
        let gwen2 = UIImage(named: "g.jpg")
        
            
        if let imageData = gwen.self?.pngData() {
            CoredataHandler.shareInstance.saveImage(data: imageData)
        }
        
        if let imageData2 = gwen2.self?.pngData() {
            CoredataHandler.shareInstance.saveImage(data: imageData2)
        }
        
        if let imageData3 = gwen.self?.pngData() {
            CoredataHandler.shareInstance.saveImage(data: imageData3)
        }
        
    }
    
    
    @objc func press(){
        

        
        CoredataHandler.shareInstance.saveImage(data: 1)
        
    
    

    return
    }


}


class CoredataHandler : NSManagedObject {
    static let shareInstance = CoredataHandler()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext


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

    return appDelegate.persistentContainer.viewContext
}
    func saveImage(data: Data) {
        let imageInstance = Information(context: context)
        
        
        imageInstance.pic = data
            
        do {
            try context.save()
          
        } catch {
            print(error.localizedDescription)
        }
    }
}
  • Core Data records are stored unordered. To *overwrite* an item you have to fetch, modify and re-save it. And consider to save an image to disk directly and keep only the (relative) URL in Core Data. – vadian Dec 23 '22 at 05:48
  • This is almost the same as [a question you asked recently](https://stackoverflow.com/questions/74839075/save-binary-data-in-core-core-data-in-specific-slot/74843252). I tried to explain that `UIImage` is a single image, not a collection, so saving three images is not something that can happen without an array or other structure. I don’t know how else to explain that. This is not a thing that `UIImage` does. – Tom Harrington Dec 23 '22 at 17:03
  • @TomHarrington to do this operation would you declare the array as a variable like you do with a string? – John Zalubski Dec 23 '22 at 19:13

1 Answers1

0

If you want a Core Data entity that can store more than one image, you have a few options:

Declare multiple image properties

Instead of just having a pic property, have more than one. As many as you like. Name them pic1, pic2, pic3, etc, or whatever seems best for your app. In code, read or write whichever makes sense at the time.

This is easy but not flexible, since your code can only save up to the number of attributes you declare in the model.

Use an array property with transformable

With a transformable attribute you can store any data that can be converted to a Data. In your case you'd do something like this:

enter image description here

Two things to notice: The type is transformable, and the custom class is [Data]. Xcode will generate code where the property type is [Data]?. You can save as many Data blobs as you want in it, representing however many images you want.

This is also easy but may use a lot of memory, because you can't access one image without loading all of them into memory at once. If you always load all of them anyway then it's no different. If you often load only one of them, this technique might use a lot more memory (e.g. 4 images would mean around 4x as much memory used).

Use a separate entity to hold the image and a to-many relationship

With this approach you'd create a new Core Data entity that only holds the image. Your existing entity would have a to-many relationship to this entity. You'd create as many image-only instances as you want, and the relationship would mean they were all available at any time.

You would probably want to make sure the to-many relationship is ordered, otherwise the images would be an unordered set that could be in any order.

This is a little more complex to write but it's flexible and doesn't have the potential memory problems of other approaches.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170