0

I want to let my users add/save photos using PhotosPicker and CoreData but I'm struggling quite a lot. Actually, I'm fine with IDs, Dates, Values and Strings but not really with Images.

I guess everything I need is in this page: https://www.hackingwithswift.com/forums/swiftui/saving-images-with-core-data-in-swiftui/1241 but I don't know why I just can't process it at all.

Would love to see if someone can tell me what should I write in place of comments below? Thanks!

// ContentView.swift
import SwiftUI

struct ContentView: View {
    @FetchRequest(sortDescriptors: [SortDescriptor(\.name)]) var cars: FetchedResults<Car>
    @State var showForm = false

    var body: some View {
        VStack {
            Button("Add a car", action: { showForm = true })
                .fullScreenCover(isPresented: $showForm, content: { FormView() })
            ForEach(cars) { car in
                Text(car.name!)
                // Image(car.image) ???
            }
        }
    }
}
// FormView.swift
import SwiftUI
import PhotosUI

struct FormView: View {
    @Environment(\.managedObjectContext) var viewContext
    @Environment(\.dismiss) var dismiss
    @State var name = ""
    // @State var image = of type ??? from @Binding ???

    var body: some View {
        VStack {
            if #available(iOS 16.0, *) {
                TextField("Name of the car", text: $name)
                PhotosView(image: $image) // @Binding an image ???
                Button("Add", action: {
                    DataController.shared.addCar(name: name, /* image: of type ??? */, context: viewContext)
                    dismiss()
                })
            } else {
                Text("Sorry, you can't add a car!")
            }
        }
    }
}

@available(iOS 16.0, *)
struct PhotosView: View {
    @State var selectedImage: PhotosPickerItem? = nil
    @State var selectedImageData: Data? = nil
    // @Binding var image: of type ???

    var body: some View {
        if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
            ZStack {
                Image(uiImage: uiImage)
                    // .onAppear { image = something } ???
                Button("Close", action: { /* Something = nil ??? */ })
            }
        } else {
            PhotosPicker("Select an image", selection: $selectedImage, matching: .images, photoLibrary: .shared())
                .onChange(of: selectedImage) { newImage in
                    Task {
                        if let data = try? await newImage?.loadTransferable(type: Data.self) { selectedImageData = data }
                    }
                }
        }
    }
}
// CarModel.xcdatamodeld
// Entity: Car
// Attributes: id (UUID), name (String) and image (Binary Data + Allows External Storage)
// DataController.swift
import Foundation
import CoreData

struct DataController {
    // Some lines of code
    func save(context: NSManagedObjectContext) {
        try? context.save
    }
    func addCar(name: String, /* image: of type ??? */, context: NSManagedObjectContext) {
        let car = Car(context: context)
        car.id = UUID()
        car.name = name
        // car.image = of type ???
        save(context: context)
    }
}
Alexnnd
  • 429
  • 4
  • 13
  • Images don't belong in CoreData, you can save the URL or the filename. There are many articles online that describe how to store images with CoreData – lorem ipsum Apr 16 '23 at 16:53
  • That's why I have selected "Allows External Storage" on my `image` attribute. – Alexnnd Apr 16 '23 at 19:34

0 Answers0