Skip to content

Instantly share code, notes, and snippets.

@benigumocom
Last active July 17, 2024 13:37
Show Gist options
  • Save benigumocom/8537635d31aa53e0fe58e4eddfc771df to your computer and use it in GitHub Desktop.
Save benigumocom/8537635d31aa53e0fe58e4eddfc771df to your computer and use it in GitHub Desktop.
【SwiftData】バックグラウンドで @Modelactor を singleton で使う 👉 https://android.benigumo.com/20240717/background-modelactor/
import SwiftUI
import SwiftData
// https://forums.developer.apple.com/forums/thread/736226
struct TestModelActorView: View {
@Environment(\.modelContext) private var modelContext
// private var dataSource: DataSource {
// // ModelActor
// DataSource(modelContainer: modelContext.container)
// }
@State private var count = 0
@State private var task: Task<Void, Error>?
var body: some View {
VStack {
Text("\(count)")
Button("fetch") {
task = Task {
//let items = await dataSource.fetch()
//let items = await DataSource(modelContainer: modelContext.container).fetch()
let items = await DataSource.shared.fetch()
count = items.count
}
}
Button("cancel") {
task?.cancel()
}
}
.buttonStyle(.borderedProminent)
// .onAppear { // main
// DataSource.createInstance(modelContainer: modelContext.container)
// }
.task { // not main
await DataSource.createInstance(modelContainer: modelContext.container)
}
}
}
@ModelActor
actor DataSource {
nonisolated(unsafe) private(set) static var shared: DataSource!
//
// static func createInstance(modelContainer: ModelContainer) {
// print("createInstance()", Thread.current) // main
// shared = DataSource(modelContainer: modelContainer)
// }
//
static func createInstance(modelContainer: ModelContainer) async {
print("createInstance()", Thread.current) // not main
shared = DataSource(modelContainer: modelContainer)
}
func fetch() async -> [Item] {
//print("fetch()", Thread.current) // depends on creating instance
do {
let items = try modelContext.fetch(FetchDescriptor<Item>())
//let items: [Item] = []
//try await Task.sleep(for: .seconds(3))
return items
} catch {
if Task.isCancelled {
print("canceled")
}
return []
}
}
}
extension Item: @unchecked Sendable {}
#Preview {
TestModelActorView()
.dataContainer()
.padding()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment