У меня есть класс модели представления, в сочетании с представлением Swiftui, которые извлекают фильтрованные записи из SwiftData с использованием моделитора. Я использовал Swiftui .task (id
Код: Выделить всё
@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)
}
}
}
Код: Выделить всё
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)
}
}
}
попытки и исследования
[*] Я рассматривал ручные (инициированные пользователем триггеры обновления, такие как 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
Мобильная версия