How to save complex model with UIImages?

I’m working on an iOS project where I have a complex model containing several nested submodels. Here’s a simplified version of my model:

struct CollageConfiguration {
    var gridConfig: GridConfiguration
    var backgroundConfig: BackgroundConfig
    var aspectRatio: AspectRatio
    var imageConfigs: [ImageConfig]
    var borderConfiguration: BorderConfig
    var labelConfigs: [LabelConfig]
    var stickerConfigs: [StickerConfig]
    var photoFrameConfig: PhotoFrameConfig?
}

Some of these submodels include images. For example:

struct StickerConfig {
    let id: UUID
    let image: UIImage
    var center: CGPoint
    var size: CGSize
    var transform: CGAffineTransform
}

struct BackgroundConfig {
    var backgroundType: BackgroundType
    var opacity: CGFloat
}

enum BackgroundType: Equatable {
    case color(UIColor)
    case gradient([UIColor])
    case image(UIImage)
}

The Problem:

I need to save this entire model to disk using FileManager, but UIImage doesn’t conform to Codable, making direct saving impossible. Also, saving UIImage directly isn’t ideal, as it should be converted to Data for more efficient storage.

Approaches I’ve Considered:

  1. Custom CodableImage Class: I could create a custom CodableImage class that handles the conversion of UIImage to Data and vice versa. By replacing all UIImage properties in my models with CodableImage, I could make the entire CollageConfiguration model conform to Codable. This is straightforward but inefficient because it would require loading the entire model (including all images) into memory, even if only a small part of the model is needed.
  2. Storing Images Separately in FileManager: Another approach is to save images separately in the file system and store only their file paths in the model. This keeps the model lightweight and avoids memory overhead when passing it around. However, implementing this involves challenges such as:
    • Managing file paths and ensuring they remain valid when images are deleted or modified.
    • Handling concurrency and error management when saving or reading multiple images simultaneously.
    • Ensuring that changes to the model are reflected in the file system inside UI flow(e.g., deleting an image when it’s removed from the model by user).
  3. Core Data with External Storage: I could use Core Data, with external storage for images. While Core Data can manage relationships and persistence, it adds complexity and requires conversion logic to handle UIImage as Data.
  4. Storing Images as Data: Alternatively, I could store images directly as Data within the model and provide a computed property to convert Data to UIImage. This avoids the Codable issue but introduces other problems:• Potential lag when converting Data to UIImage in the UI.• Memory overhead due to large data blobs being copied during model updates, especially with features like UndoManager.

Given these considerations, what is the best approach to store a complex model that includes nested models with UIImage?

I’m leaning towards storing images separately in FileManager and keeping references in the model, but I’m unsure how to efficiently manage this, particularly in terms of concurrency, error handling, and keeping the model lightweight. I would appreciate advice on how experienced developers handle similar scenarios, or if there’s a more optimal approach I haven’t considered.