我正在使用MKLocalSearch来允许用户搜索他们的城市。然而,当我尝试代码时,我只在美国收到结果。我也收到了很多结果,包括商店等。我在func completerDidUpdateResults(_ completer: MKLocalSearchCompleter)
中添加了过滤器,以消除不是城市的结果。这是可行的,但我觉得这可能会失败的某些地方。我尝试添加下面的代码,但没有工作。我会很感激你的帮助。
let worldRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 0, longitude: 0),
span: MKCoordinateSpan(latitudeDelta: 180, longitudeDelta: 360))
self.searchCompleter.region = worldRegion
import Foundation
import Combine
import MapKit
class LocationService: NSObject, ObservableObject {
enum LocationStatus: Equatable {
case idle
case noResults
case isSearching
case error(String)
case result
}
@Published var queryFragment: String = ""
@Published private(set) var status: LocationStatus = .idle
@Published private(set) var searchResults: [MKLocalSearchCompletion] = []
private var queryCancellable: AnyCancellable?
private let searchCompleter: MKLocalSearchCompleter!
init(searchCompleter: MKLocalSearchCompleter = MKLocalSearchCompleter()) {
self.searchCompleter = searchCompleter
super.init()
self.searchCompleter.delegate = self
queryCancellable = $queryFragment
.receive(on: DispatchQueue.main)
.debounce(for: .milliseconds(250), scheduler: RunLoop.main, options: nil)
.sink(receiveValue: { fragment in
self.status = .isSearching
if !fragment.isEmpty {
self.searchCompleter.queryFragment = fragment
} else {
self.status = .idle
self.searchResults = []
}
})
}
}
extension LocationService: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
self.searchResults = completer.results.filter { result in
if !result.title.contains(",") {
return false
}
if result.title.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil {
return false
}
if result.subtitle.rangeOfCharacter(from: CharacterSet.decimalDigits) != nil {
return false
}
return true
}
self.status = completer.results.isEmpty ? .noResults : .result
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
self.status = .error(error.localizedDescription)
}
}
import SwiftUI
import MapKit
struct locView: View {
@StateObject var locationService = LocationService()
var body: some View {
VStack {
Form {
Section(header: Text("Location Search")) {
ZStack(alignment: .trailing) {
TextField("Search", text: $locationService.queryFragment)
if locationService.status == .isSearching {
Image(systemName: "clock")
.foregroundColor(Color.gray)
}
}
}
Section(header: Text("Results")) {
List {
Group { () -> AnyView in
switch locationService.status {
case .noResults: return AnyView(Text("No Results"))
case .error(let description): return AnyView(Text("Error: \(description)"))
default: return AnyView(EmptyView())
}
}.foregroundColor(Color.gray)
ForEach(locationService.searchResults, id: \.self) { completionResult in
Text(completionResult.title)
}
}
}
}
}
}
}
1条答案
按热度按时间3wabscal1#
以下是一些观察结果:
1.要从商店之类的东西中排除搜索兴趣点,您可以指定完成程序只搜索地址(例如:a
resultTypes
of.address
):字符串
或者,您可以显式排除具有
pointsOfInterestFilter
或.excludingAll
的兴趣点:型
1.您的
completerDidUpdateResults(_:)
实现正在过滤结果(可能是Search for Place Names (City/Town) Using MKLocalSearchCompleter的改编,它假设城市的title
必须包含逗号)。例如,搜索“慕尼黑”,您将返回两个结果“Munich,ND”/“United States”和“Munich”/“Bavaria,德国”。因为您要在title
中查找逗号,后面的结果将随后被过滤掉。这说明了试图查看字符串特征来确定
title
/subtitle
组合是否代表一个城市是多么的脆弱。1.您可以考虑使用
MKLocalSearch
或CLGeocoder
,但是虽然这两种方法都返回结果数组,但我发现它们的结果比MKLocalSearchCompleter
更窄。在“慕尼黑”搜索示例中,这两个都只返回德国的城市。总之,MapKit和CoreLocation似乎没有提供简单的城市搜索功能。我知道Google Maps API是这样做的(但显然也要求,如果你在实际Map上显示结果,你只能在GoogleMap上显示,而不是MapKit的)。