#swift #core-data #swiftui
Вопрос:
Следующий код успешно сохраняет Car
сущности в Core Data
. Как вы можете видеть Car
, у сущности есть атрибут Binary Data
, в котором я сохраняю изображение, чтобы использовать его в качестве миниатюры. Моя проблема с приведенным ниже кодом заключается в том, что если пользователь решит не добавлять изображение в некоторые из Car
s, мне нужно предоставить изображение по умолчанию, единственный вариант, который я могу придумать defaultCarImage
, — это поместить его в Assets
папку, а затем вызвать его и сохранить для автомобилей, для которых пользователь не выбрал изображение. Моя проблема с этим подходом заключается в том, что если пользователь решит не использовать изображения для любого из своих автомобилей, я буду сохранять одно и то же изображение в десятках или сотнях автомобилей. Есть ли способ каким-то образом повторно использовать изображение, в котором оно уже сохранено Core Data
?
Каков правильный подход к предоставлению изображения по умолчанию для Car
объектов, для которых пользователь не предоставил изображение?
сущность
Car
Атрибут
carImage Binary Data (Allows External Storage)
make String
model String
Менеджер основных данных
import SwiftUI
import CoreData
class CoreDataManager{
static let instance = CoreDataManager()
let container: NSPersistentContainer
let context: NSManagedObjectContext
init(){
container = NSPersistentContainer(name: "CoreDataContainer")
container.loadPersistentStores { (description, error) in
if let error = error{
print("Error loading Core Data. (error)")
}
}
context = container.viewContext
}
func save(){
do{
try context.save()
print("Saved successfully!")
}catch let error{
print("Error saving Core Data. (error.localizedDescription)")
}
}
}
Модель Основных Данных
import Foundation
import CoreData
import UIKit
class CoreDataViewModel: ObservableObject{
let manager = CoreDataManager.instance
@Published var cars: [Car] = []
func addCar(make: String, model: String, image:UIImage){
let imageData = image.jpegData(compressionQuality: 0.1)
let car = Car(context: manager.context)
car.make = make
car.model = model
car.carImage = imageData
save()
getCars()
}
}
Просмотр содержимого
struct ContentView: View {
@StateObject var coreDataViewModel = CoreDataViewModel()
@State private var makeInput:String = ""
@State private var modelInput:String = ""
@State private var carImageFromPicker: UIImage?
var body: some View {
VStack{
if let inputImage = carImageFromPicker {
Image(uiImage: inputImage)
.resizable()
.onTapGesture {
// show camera
}
} else {
Image(systemName: "car.fill")// default image
.onTapGesture {
// show camera
}
}
Button(action: {
saveNewCar()
}) {
Text("Save")
}
}
}
func saveNewCar(){
coreDataViewModel.addCar(make: makeInput, model: modelInput, image: carImageFromPicker!)
}
}
Комментарии:
1. Ваш код сохранит только изображение, выбранное из средства выбора изображений (возможно, какой-то код отсутствует), поэтому сохраните его таким образом и сделайте свойство изображения необязательным. Затем вы можете использовать одно изображение по умолчанию всякий раз, когда свойство изображения автомобиля равно нулю
2. Я сделал
carImage
необязательный параметр в Основных данных. Итак, теперь для объектов без изображения я просто предоставляю пустыеData()
илиData(count:0)
основные данные? Опять же, чего я пытаюсь избежать, так это многократного сохранения одного и того же изображения в основных данных.3. Кажется, я понял. После внесения
carImage
необязательных изменений в основные данные я предоставляю пустоеData()
поле для объектов без изображений и используюdefaultImage
папку «Ресурсы» только для визуальных целей. Спасибо, что указали на тот факт, что двоичные данные могут быть необязательными.4. Если свойство является необязательным, то оно вам не нужно
Data()
. Оставьте собственность в покое, и она будет равна нулю. Или установите его равным нулю, чтобы было понятно, если вы предпочитаете.