Нужно ли мне извлекать запись каждый раз, когда я обновляю существующий объект Core Data Entity, или я могу использовать массивы @published для изменения данных?
Я изучаю SwiftUI и работаю над проектом приложения iOS со SwiftUI, где я использовал Core Data для постоянного хранения данных. Я создал глобальную модель представления и ввел ее в среду сверху, чтобы иметь доступ к ней в своем приложении из любого места.
App.swift
@main
struct AppName: App {
@StateObject var viewModel = AppViewModel()
var body: some Scene {
WindowGroup {
HomeScreenView()
.environmentObject(viewModel)
}
}
я создал@Published
массивы, которые содержат существующие объекты основных сущностей данных. Я использую их для отображения значений внутри моего представления.
ViewModel.swift
class AppViewModel: ObservableObject {
@Published var entityAs: [EntityA] = []
@Published var entityBs: [EntityB] = []
@Published var entityCs: [EntityC] = []
...
init() {
//load data in variables
loadEntityAs()
loadEntityBs()
loadEntityCs()
...
}
func loadEntityAs() {
let request = NSFetchRequest<EntityA>(entityName: EntityNames.EntityA.rawValue)
do {
self.entityAs = try CoreDataManager.shared.context.fetch(request)
} catch let error {
print("Unable to fetch entity data: \(error.localizedDescription)")
}
}
...
Я использовал singleton для постоянных данных и вызываю его, когда мне нужно сохранить данные.Настойчивость.swift
class CoreDataManager {
static let shared = CoreDataManager() //Singleton
let context: NSManagedObjectContext
let container: NSPersistentContainer
private init() {
container = NSPersistentContainer(name: "App_Name")
container.loadPersistentStores { description, error in
if let error = error {
print("Error loading core data: \(error)")
}
}
self.context = container.viewContext
}
func save() {
do {
if context.hasChanges {
try context.save()
}
} catch let error {
print("Error saving Core Data: \(error.localizedDescription)")
}
}
func delete(_ entity: NSManagedObject) {
context.delete(entity)
save()
}
}
Сейчас я создаю представления, в которых пользователь может изменять существующие значения сущностей, например, для изменения имени. Я могу представить 2 варианта. Какая лучшая практика здесь?
Создание функции под названием
fetchEntityA(name: String)
для получения требуемого объекта по его имени. Затем измените его значение, а затем вызовитеCoreDataManager.shared.save()
Зацикливание
@Published var entityAs
и получение требуемой сущности с последующим изменением ее значения и последующим сохранением.
Я не уверен, будет ли работать вариант 2 или нет. Я использовал вариант 1 в своем последнем проекте, и он отлично работает. Но я не уверен, что я переусердствую здесь.
Кроме того, этот метод использования@Published var entityAs: [EntityA]
лучше использовать внутри представлений SwiftUI? я не использовал@FetchedResults
раньше, и я не уверен, как мне сравнить эти два подхода.
Текущая установка, о которой я думаю (вариант 1):EntityDetailsView.swift
struct EntityDetails: View {
@EnvironmentObject var vm: AppViewModel
let entity: EntityA
@State var name = ""
@State var type = ""
var body: some View {
VStack {
Text("Entity Details")
TextField(name, text: $name)
TextField(type, text: $type)
Button("Save") {
vm.updateEntityA(entity, newName: name, newType: type)
}
}
.onAppear {
self.name = entity.name ?? ""
self.type = entity.type ?? ""
}
}
}
Ранее я использовал первый вариант, т.е. создание функции, которая будет получать требуемый объект, изменять его значение и сохранять его. Это работает нормально. Но я хочу изучить другие идеи, поскольку написание этих функций для получения каждой сущности, которая есть в моем приложении, и написание функций обновления для каждой сущности немного раздражает. Должен быть более оптимальный способ сделать это.