import SwiftUI
import GooglePlaces
struct Place: Identifiable {
var id = UUID().uuidString
let name: String
let identifier: String
}
class GooglePlaceManager: ObservableObject {
@Published var places: [Place] = []
static let shared = GooglePlaceManager()
private let client = GMSPlacesClient.shared()
enum PlacesError: Error {
case failedToFind
}
public func findPlaces(
query: String) {
let filter = GMSAutocompleteFilter()
filter.type = .geocode
client.findAutocompletePredictions(
fromQuery: query,
filter: filter,
sessionToken: nil) { (res, error) in
guard let res = res, error == nil
else {
return
}
let places: [Place] = res.compactMap {
Place(name: $0.attributedFullText.string, identifier: $0.placeID)
}
self.places = places
}
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
TestView()
.onAppear {
GMSPlacesClient.provideAPIKey("API-Key")
}
}
}
}
struct TestView: View {
@StateObject var googlePlaceManager = GooglePlaceManager()
@State var text = ""
var body: some View {
VStack{
TextField("Search place ...", text: $text)
.onChange(of: text, perform: { _ in
googlePlaceManager.findPlaces(query: text)
})
VStack {
ScrollView {
ForEach(googlePlaceManager.places) { place in
Text(place.name)
.font(.body)
.foregroundColor(.blue)
}
}
}
Spacer()
}
}
}
I tried onAppear, but it's not working.
Error: Terminating app due to uncaught exception 'GMSPlacesException', reason: 'Google Places SDK for iOS must be initialized via [GMSPlacesClient provideAPIKey:...] prior to use'
(But if it is possible to add AppDelegate to SwiftUI, you can also show it if it can solve the problem)