Skip to content

Instantly share code, notes, and snippets.

@mshafer
Last active February 13, 2022 03:47
Show Gist options
  • Save mshafer/cdae4de0d7b5a13c5765affdb91ddb34 to your computer and use it in GitHub Desktop.
Save mshafer/cdae4de0d7b5a13c5765affdb91ddb34 to your computer and use it in GitHub Desktop.
MKLocalSearchCompleter results in SwiftUI using Combine. More explanation: https://www.mozzafiller.com/posts/mklocalsearchcompleter-swiftui-combine
import Foundation
import SwiftUI
import MapKit
import Combine
class LocationSearchService: NSObject, ObservableObject, MKLocalSearchCompleterDelegate {
@Published var searchQuery = ""
var completer: MKLocalSearchCompleter
@Published var completions: [MKLocalSearchCompletion] = []
var cancellable: AnyCancellable?
override init() {
completer = MKLocalSearchCompleter()
super.init()
cancellable = $searchQuery.assign(to: \.queryFragment, on: self.completer)
completer.delegate = self
}
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
self.completions = completer.results
}
}
extension MKLocalSearchCompletion: Identifiable {}
import SwiftUI
struct MKLocalSearchCompleterExampleView: View {
@ObservedObject var locationSearchService: LocationSearchService
var body: some View {
NavigationView {
VStack {
SearchBar(text: $locationSearchService.searchQuery)
List(locationSearchService.completions) { completion in
VStack(alignment: .leading) {
Text(completion.title)
Text(completion.subtitle)
.font(.subheadline)
.foregroundColor(.gray)
}
}.navigationBarTitle(Text("Search near me"))
}
}
}
}
// Create the SwiftUI view that provides the window contents.
let locationSearchService = LocationSearchService()
let contentView = MKLocalSearchCompleterExampleView(locationSearchService: locationSearchService)
import SwiftUI
struct SearchBar: UIViewRepresentable {
@Binding var text: String
class Coordinator: NSObject, UISearchBarDelegate {
@Binding var text: String
init(text: Binding<String>) {
_text = text
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
text = searchText
}
}
func makeCoordinator() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
func makeUIView(context: UIViewRepresentableContext<SearchBar>) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
searchBar.searchBarStyle = .minimal
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext<SearchBar>) {
uiView.text = text
}
}
@Mcrich23
Copy link

I also get a bunch of errors:

2022-02-12 19:45:59.095462-0800 Pickt[64199:2417526] [SearchAttribution] No matching attribution source found for com.timeout
2022-02-12 19:45:59.095595-0800 Pickt[64199:2417526] [SearchAttribution] No matching attribution source found for com.theculturetrip
2022-02-12 19:45:59.095822-0800 Pickt[64199:2417526] [SearchAttribution] No matching attribution source found for com.redtri
2022-02-12 19:45:59.095909-0800 Pickt[64199:2417526] [SearchAttribution] No matching attribution source found for com.fotospot
2022-02-12 19:45:59.096549-0800 Pickt[64199:2417526] [SearchAttribution] Error loading attribution info for identifier com.timeout from geod: Error Domain=GEOErrorDomain Code=-8 "No matching attribution source found for com.timeout" UserInfo={NSDebugDescription=No matching attribution source found for com.timeout}
2022-02-12 19:45:59.096679-0800 Pickt[64199:2417526] [SearchAttribution] Error loading attribution info for identifier com.theculturetrip from geod: Error Domain=GEOErrorDomain Code=-8 "No matching attribution source found for com.theculturetrip" UserInfo={NSDebugDescription=No matching attribution source found for com.theculturetrip}
2022-02-12 19:45:59.096761-0800 Pickt[64199:2417526] [SearchAttribution] Error loading attribution info for identifier com.redtri from geod: Error Domain=GEOErrorDomain Code=-8 "No matching attribution source found for com.redtri" UserInfo={NSDebugDescription=No matching attribution source found for com.redtri}
2022-02-12 19:45:59.096837-0800 Pickt[64199:2417526] [SearchAttribution] Error loading attribution info for identifier com.fotospot from geod: Error Domain=GEOErrorDomain Code=-8 "No matching attribution source found for com.fotospot" UserInfo={NSDebugDescription=No matching attribution source found for com.fotospot}

And more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment