Как обновить SwiftData (ручное) принесение всякий раз, когда изменяется база данных?IOS

Программируем под IOS
Ответить
Anonymous
 Как обновить SwiftData (ручное) принесение всякий раз, когда изменяется база данных?

Сообщение Anonymous »

Сводка < /h2>
У меня есть класс модели представления, в сочетании с представлением Swiftui, которые извлекают фильтрованные записи из SwiftData с использованием моделитора. Я использовал Swiftui .task (id :) , чтобы запустить повторные загрузки в модели представления всякий раз, когда изменяется мой предикат фильтра, но я хочу также запустить повторные загрузки всякий раз, когда сама база данных обновляется на протяжении всего моего пользовательского интерфейса. Как я могу сообщить модели представления о повторной загрузке всякий раз, когда SwiftData Comming My insert () и удалить () вызовы? Традиционные @Query Настройки не предоставили той гибкости, которую я хотел (в частности, для рендеринга состояний загрузки), поэтому я создал фонового актера для обработки данных:

Код: Выделить всё

@ModelActor
actor ThreadsafeBackgroundActor: Sendable {
func fetchData(_ predicate: Predicate? = nil) throws -> [CardView] {
let descriptor = if let p = predicate {
FetchDescriptor(predicate: p)
} else {
FetchDescriptor()
}
let cards = try context.fetch(descriptor)
return cards.map(CardView.init)
}
}
< /code>
У меня также есть модель представления, называемая актером: < /p>
@Observable
class CardListViewModel {
enum State {
case idle
case loading
case failed(Error)
case loaded([CardView])
}

private(set) var state = State.idle

func fetchData(container: ModelContainer, predicate: Predicate) async throws -> [CardView] {
let service = ThreadsafeBackgroundActor(modelContainer: container)
return try await service.fetchData(predicate)
}

@MainActor func load(container: ModelContainer, filter: CardPredicate) async {
state = .loading

do {
let cards = try await fetchData(container: container, predicate: filter.predicate)
state = .loaded(cards)
} catch is CancellationError {
state = .idle
} catch {
state = .failed(error)
}
}
}
И у меня есть задача в моем представлении Swiftui, чтобы начать начальную нагрузку:

Код: Выделить всё

struct CardListView: View {
@State private var viewModel = CardListViewModel()
@Environment(\.modelContext) private var context
@Binding var cardFilter: CardPredicate

init() { /* Initialize bindings */ }

var body: some View {
Group { ... }
.task(id: cardFilter) { // Reloads whenever the card filter changes! Good!
viewModel.load(container: context.container, filter: cardFilter)
}
}
}
Эта настройка работает превосходно до тех пор, пока действия в представлении не обновит что -либо в базе данных . Действия ModelContext, например, context.insert () и context.delete () , не запускайте мою функцию загрузки . Вызов context.save () не заставляет обновление. Позволить SwiftData работать с минимальным вмешательством от меня является целью.
попытки и исследования

[*] Я рассматривал ручные (инициированные пользователем триггеры обновления, такие как List . Хотя это полезно для пользователей, которые знают, что им нужны обновленные данные, я не хочу, чтобы достоверность представленных данных зависела от вмешательства пользователя. Области кода, которые обновляют приращение базы данных RELOADCOUNT , и отдельную задачу в моем списке Просмотр Просмотр Смотрите счет:

Код: Выделить всё

.task(id: cardFilter) { /* Same call */ }
.task(id: reloadCount) { // Eww...
viewModel.load(container: context.container, filter: cardFilter)
}
Не только эта стратегия утомительна и хрупкая, но также не работает риск вызовой нагрузки несколько раз без необходимости (особенно во время первоначального рендеринга).

[*] Я рассмотрел систему потокового уведомления Swift. Я совершенно уверен, что nspersistentstoreremotechange - это то, что я хочу посмотреть. Я просто не могу понять, как/где инициализировать этого наблюдателя. AddObserver запрашивает аннотации Objective-C. Я не думаю, что .publisher (). Snin {} также является решением, потому что я хочу начать мутирующее вызов viewmodel.load () в (сбегающем) закрытии.



Подробнее здесь: https://stackoverflow.com/questions/797 ... is-changed
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»