Bonjour I am new in swift and Xcode I want to use the search bar to fetch the titles following what is typed
I get this error:
Type '() -> ()' cannot conform to 'StringProtocol'
import SwiftUI
import SQLite3
struct ContentView: View {
@State var cantiques = [[String: String]]()
@State private var searchText = ""
var body: some View {
NavigationView {
VStack {
List(cantiques, id: \.self) { cantique in
NavigationLink(
destination: hymnesetlouangesafficher(cantique: cantique),
label: {
Text("\(cantique["ref"] ?? "") - \(cantique["titre"] ?? "")")
})
}
}
.navigationTitle("Hymnes et Louanges")
.searchable(text: $searchText) { searchText in
fetchCantiqueTitles(searchText: searchText)
}
}
.onAppear {
fetchCantiqueTitles(searchText: "")
}
}
func fetchCantiqueTitles(searchText: String) {
cantiques.removeAll()
var db: OpaquePointer?
let dbPath = Bundle.main.path(forResource: "Hymnes_et_Louanges", ofType: "db")!
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Database opened successfully")
} else {
print("Database not opened - problem")
return
}
let query = "SELECT ref, titre FROM cantiques WHERE titre LIKE '%\(searchText)%'"
var statement: OpaquePointer?
if sqlite3_prepare_v2(db, query, -1, &statement, nil) == SQLITE_OK {
while sqlite3_step(statement) == SQLITE_ROW {
if let ref = sqlite3_column_text(statement, 0), let titre = sqlite3_column_text(statement, 1) {
let refString = String(cString: ref)
let titreString1 = String(cString: titre)
let titreString2 = titreString1.replacingOccurrences(of: "\\n", with: "")
let titreString3 = titreString2.replacingOccurrences(of: "`", with: "'")
let titreString = titreString3.replacingOccurrences(of: "...", with: "")
cantiques.append(["ref": refString, "titre": titreString])
}
}
} else {
print("Error preparing query")
}
sqlite3_finalize(statement)
sqlite3_close(db)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Merci bien
If I understand your point, you should
- Change the func
func fetchCantiqueTitles(searchText: String) {
to return an array [Cantique]
typealias Cantique = [String: String]
func fetchCantiqueTitles(searchText: String) -> [Cantique] { // <<-- ADD return value
var fetchedCantiques = [Cantique]() // <<-- CHANGE HERE cantiques.removeAll()
var db: OpaquePointer?
let dbPath = Bundle.main.path(forResource: "Hymnes_et_Louanges", ofType: "db")!
if sqlite3_open(dbPath, &db) == SQLITE_OK {
print("Database opened successfully")
} else {
print("Database not opened - problem")
return
}
let query = "SELECT ref, titre FROM cantiques WHERE titre LIKE '%\(searchText)%'"
var statement: OpaquePointer?
if sqlite3_prepare_v2(db, query, -1, &statement, nil) == SQLITE_OK {
while sqlite3_step(statement) == SQLITE_ROW {
if let ref = sqlite3_column_text(statement, 0), let titre = sqlite3_column_text(statement, 1) {
let refString = String(cString: ref)
let titreString1 = String(cString: titre)
let titreString2 = titreString1.replacingOccurrences(of: "\\n", with: "")
let titreString3 = titreString2.replacingOccurrences(of: "`", with: "'")
let titreString = titreString3.replacingOccurrences(of: "...", with: "")
fetchedCantiques.append(["ref": refString, "titre": titreString]) // <<-- CHANGE HERE cantiques.append(["ref": refString, "titre": titreString])
}
}
} else {
print("Error preparing query")
}
sqlite3_finalize(statement)
sqlite3_close(db)
return fetchedCantiques // <<-- ADD THIS
}
- change the filteredCantiques var:
var filteredCantiques: [Cantique] {
if searchText.isEmpty {
return cantiques
} else {
return fetchCantiqueTitles(searchText: searchText)
}
}
- And change the body of ContentView:
var body: some View {
NavigationView {
VStack {
List(filteredCantiques, id: \.self) { cantique in // <<-- CHANGE HERE
NavigationLink(
destination: hymnesetlouangesafficher(cantique: cantique),
label: {
Text("\(cantique["ref"] ?? "") - \(cantique["titre"] ?? "")")
})
}
}
.navigationTitle("Hymnes et Louanges")
.searchable(text: $searchText) // <<-->> CHANGE { searchText in fetchCantiqueTitles(searchText: searchText) }
}
.onAppear {
cantiques = fetchCantiqueTitles(searchText: "") // <<-- CHANGE
}
Hopefully I did not forget anything…