在后台,我尝试解析包含 40,000 多个机场名称的 CSV 文件。这个想法是在应用程序首次启动时在后台解析它并使用 SwiftData 将其保存到数据库。但当解析开始时,用户界面就会冻结。哪里错了?
//--编辑--//
按照建议,我修改了代码以限制被过滤的机场数量,避免每个周期都保存数据库。
但是当我尝试在查询中使用谓词或获取描述符时,我遇到以下错误(见下文)
Instance member 'descriptor' cannot be used on type 'Airports'; did you mean to use a value of this type instead?
import SwiftUI
import SwiftData
struct Airports: View {
var descriptor = FetchDescriptor<Airport>()
@Query(descriptor) var aptshort: [Airport] //<----error
var pr = #Predicate<Airport> { apt in
apt.icao.contains("V")
}
@Query(filter: pr,//<----error
sort: [SortDescriptor(\Airport.lastPicked,order: .reverse)],
animation: .default) var aptshort2: [Airport]
var body: some View {
List{
Text("Airport Contains : \(aptshort.count)")
ForEach(aptshort) { apt in
Text("icao: \(apt.icao)")
}
}
}
}
actor AirportParser: ModelActor {
let executor: any ModelExecutor
let context: ModelContext
init(modelContainer: ModelContainer) {
context = ModelContext(modelContainer)
executor = DefaultModelExecutor(context: context)
}
func parseDBAirport() async {
guard let file = Bundle.main.path(forResource: "airports", ofType: "csv") else {return}
let url = URL(filePath: file)
do {
let csvFile : CSV = try CSV<Named>(url: url)
print(csvFile.rows)
for raw in csvFile.rows{
let icao = raw["ident"] ?? ""
let airport = Airport(lastPicked: Date(), icao: icao)
context.insert(airport)
}
print("finish save all airports")
do{
try context.save()
}catch {
print(error)
}
} catch let err {
print(err.localizedDescription)
}
}
}