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)
}
}