Last active
February 13, 2022 03:47
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create the SwiftUI view that provides the window contents. | |
let locationSearchService = LocationSearchService() | |
let contentView = MKLocalSearchCompleterExampleView(locationSearchService: locationSearchService) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Wow, the only usable and easily comprehensive solution out there... thank you for this contribution
how to get the address + coordinate?
Hi @saroar – the .subtitle
property on the MKLocalSearchCompletion
objects is usually the address of the result. But to get more details (e.g. coordinates) you need to convert the completion object into an MKLocalSearch. See this StackOverflow answer: How to extract country and city from MKLocalSearchCompletion?
Whenever I show the search bar in a view, it clears within a couple seconds and the search breaks, any ideas?
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
For more explanation on how this works, see this post: https://www.mozzafiller.com/posts/mklocalsearchcompleter-swiftui-combine
Result