MKLocalSearch 只产生美国结果,如何扩展搜索?

2023-12-31

我正在使用 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. 要从商店等内容中排除搜索兴趣点,您可以指定完成者应仅搜索地址(例如resultTypes https://developer.apple.com/documentation/mapkit/mklocalsearchcompleter/3143405-resulttypes of .address https://developer.apple.com/documentation/mapkit/mklocalsearchcompleter/resulttype/3143407-address):

    searchCompleter.resultTypes = .address
    

    或者,您可以使用以下命令显式排除兴趣点pointsOfInterestFilter https://developer.apple.com/documentation/mapkit/mklocalsearchcompleter/3143404-pointofinterestfilter of .excludingAll https://developer.apple.com/documentation/mapkit/mkpointofinterestfilter/3143464-excludingall:

    searchCompleter.pointOfInterestFilter = .excludingAll
    
  2. Your completerDidUpdateResults(_:)实现是过滤结果(也许是使用 MKLocalSearchCompleter 搜索地名(城市/城镇) https://stackoverflow.com/a/59233185/1271826,假设title对于城市必须包含逗号)。例如,搜索“慕尼黑”,您将返回两个结果“慕尼黑,北达科他州”/“美国”和“慕尼黑”/“巴伐利亚,德国”。因为您正在寻找逗号title,后面的结果将被过滤掉。

    这说明尝试查看字符串特征来确定字符串是否存在是多么脆弱。title/subtitle组合是否代表一个城市。

  3. 您可以考虑使用MKLocalSearch https://developer.apple.com/documentation/mapkit/mklocalsearch or CLGeocoder https://developer.apple.com/documentation/corelocation/clgeocoder,但是虽然它们都返回结果数组,但我发现它们的结果比MKLocalSearchCompleter。在“慕尼黑”搜索示例中,这两者都仅返回德国的城市。

底线是,MapKit 和 CoreLocation 似乎没有提供简单的城市搜索功能。我知道 Google Maps API 可以(但显然还要求,如果您在实际地图上显示结果,则只能在 Google 地图上显示,而不是在 MapKit 地图上显示)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MKLocalSearch 只产生美国结果,如何扩展搜索? 的相关文章

随机推荐