After long time developing in Swift with storyboard I decide to move to Swift UI. I make a small project to do that. This project is to simply read a CSV file and show some informations in a List and make this list searchable.
I've already been able to read the CSV file and then open some informations in a List. I've understand approximately how the protocol work but I'm definitely looked with the searching function ...
Here is my "mainView" code :
struct AirportView: View {
@State private var searchText = ""
@ObservedObject var airportsVM:AirportsViewModel = AirportsViewModel()
var body: some View {
let airportsDB = airportsVM.ListAirports
NavigationView {
List{
Section(header: Text("Suisse")){
Text("Hello World")
}
Section(header: Text("France")) {
ForEach(airportsDB, id:\.self) { listAirport in
NavigationLink(destination: Text(listAirport.ApType)) {
Text("\(listAirport.Icao) - \(listAirport.Name)")
}
}
}
}
.id(UUID())
}
.navigationTitle("Airports")
.searchable(text: $searchText)
.navigationViewStyle(StackNavigationViewStyle())
}
and here is my "CSV Reader" Code
import Foundation
struct Airports2: Identifiable, Codable, Hashable{
var AirportID: String = ""
var Icao: String = ""
var ApType: String = ""
var Name: String = ""
var Latitude: String = ""
var Longitude: String = ""
var Altitude: String = ""
var Continent: String = ""
var Country: String = ""
var Region: String = ""
var Municipality: String = ""
var Service: String = ""
var GpsCode: String = ""
var Iata: String = ""
var LocalCode: String = ""
var Link: String = ""
var wikiLink: String = ""
var Keyword: String = ""
let id = UUID()
}
var airportsDB = [Airports2]()
class AirportsClass {
static let
bundleURL = Bundle.main.url(forResource: "FR_Airports", withExtension: "csv")!
static func retrieveAP() -> [Airports2] {
guard let data = try? Data(contentsOf: bundleURL) else {
fatalError("Unable to load airports data")
}
let decoder = String(data: data, encoding: .utf8)
if let dataArr = decoder?.components(separatedBy: "\n").map({ $0.components(separatedBy: ",") })
{
var i = 0
for line in dataArr
{
i = 1
if i < dataArr.count {
let item = Airports2(AirportID: line[0], Icao: line[1], ApType: line[2], Name: line[3], Latitude: line[4], Longitude: line[5], Altitude: line[6], Continent: line[7], Country: line[8], Region: line[9], Municipality: line[10], Service: line[11], GpsCode: line[12], Iata: line[13], LocalCode: line[14], Link: line[15], wikiLink: line[16], Keyword: line[17])
airportsDB.append(item)
}
}
}
return airportsDB
}
}
class AirportsViewModel: NSObject, ObservableObject {
@Published var ListAirports = [Airports2]()
override init() {
ListAirports = AirportsClass.retrieveAP()
}
}
Thanks for your help !
CodePudding user response:
struct AirportView: View {
@State private var searchText = ""
private let airportsVM = AirportsClass.retrieveAP()
var filteredResults: [Airports2] {
if searchText.isEmpty {
return airportsVM.ListAirports
} else {
// some sort of filtering - you'll probably need to filter on multiple properties
return airportsVM.ListAirpots.filter { $0.Name.contains(searchText) }
}
}
var body: some View {
NavigationView {
List{
Section(header: Text("Suisse")){
Text("Hello World")
}
Section(header: Text("France")) {
ForEach(filteredResults, id:\.self) { airport in
NavigationLink(destination: Text(airport.ApType)) {
Text("\(airport.Icao) - \(airport.Name)")
}
}
}
}
.id(UUID())
}
.navigationTitle("Airports")
.searchable(text: $searchText)
.navigationViewStyle(StackNavigationViewStyle())
}
}