ios MKLocalSearch只显示美国搜索结果,如何扩展搜索?

tez616oj  于 2023-08-08  发布在  iOS
关注(0)|答案(1)|浏览(130)

我正在使用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)
                        }
                    }
                }
            }
        }
    }
}
3wabscal

3wabscal1#

以下是一些观察结果:
1.要从商店之类的东西中排除搜索兴趣点,您可以指定完成程序只搜索地址(例如:a resultTypes of .address):

searchCompleter.resultTypes = .address

字符串
或者,您可以显式排除具有pointsOfInterestFilter.excludingAll的兴趣点:

searchCompleter.pointOfInterestFilter = .excludingAll


1.您的completerDidUpdateResults(_:)实现正在过滤结果(可能是Search for Place Names (City/Town) Using MKLocalSearchCompleter的改编,它假设城市的title必须包含逗号)。例如,搜索“慕尼黑”,您将返回两个结果“Munich,ND”/“United States”和“Munich”/“Bavaria,德国”。因为您要在title中查找逗号,后面的结果将随后被过滤掉。
这说明了试图查看字符串特征来确定title/subtitle组合是否代表一个城市是多么的脆弱。
1.您可以考虑使用MKLocalSearchCLGeocoder,但是虽然这两种方法都返回结果数组,但我发现它们的结果比MKLocalSearchCompleter更窄。在“慕尼黑”搜索示例中,这两个都只返回德国的城市。
总之,MapKit和CoreLocation似乎没有提供简单的城市搜索功能。我知道Google Maps API是这样做的(但显然也要求,如果你在实际Map上显示结果,你只能在GoogleMap上显示,而不是MapKit的)。

相关问题