#ios #swift
#iOS #swift
Вопрос:
Я следую этой статье: https://www.peteralt.com/blog/mapkit-location-search-with-swiftui /
И я настроил LocationSearchService следующим образом:
extension LocationSearchService: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
self.searchResults = completer.results
self.status = completer.results.isEmpty ? .noResults : .result
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
self.status = .error(error.localizedDescription)
}
}
class LocationSearchService: 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 = []
}
})
}
}
К сожалению, я получаю подобные значения с «Поиском поблизости» в них. Как мне отфильтровать это?
Комментарии:
1. Я смог найти ответ ниже, но я использовал код, очень похожий на ваш. Я заметил, что здесь есть утечка памяти. В receiveValue я считаю, что он должен фиксироваться
[weak self]
, а затемself.
должен быть заменен наself?.
Ответ №1:
Я столкнулся с той же проблемой.
Я смог это исправить, указав, что мне нужны только адреса и достопримечательности следующим образом при настройке MKLocalSearchCompleter.
searchCompleter.resultTypes = MKLocalSearchCompleter.ResultType([.address, .pointOfInterest])
Комментарии:
1. Спасибо, Деннис, это выглядит хорошо для Swift, но я работал в ObjC. Кроме того, мы решили реализовать автозаполнение с использованием Google Maps вместо MKLocalSearchCompleter по причинам, не связанным с этой проблемой…
Ответ №2:
Я работаю над аналогичной проблемой. Класс MKLocalSearchCompleter включает свойство resultTypes
, которое, согласно документации, позволяет выбирать между:
- запрос
- PointOfInterest
- адрес
Итак, кажется, что вы хотите установить завершитель, чтобы исключить тип результата «запрос», что-то вроде:
completer.resultTypes = [.address, .pointOfInterest]
** это не рабочий код
Однако я не нашел полезного способа использовать это свойство. Моим решением было использовать строковый фильтр для удаления результатов, включающих строку «Поиск поблизости»:
- (void)completerDidUpdateResults:(MKLocalSearchCompleter *)completer {
NSMutableArray *suggestions = [[NSMutableArray alloc] init];
NSArray* results = completer.results;
for (MKLocalSearchCompletion *place in results)
{
if ([@"Search Nearby" isEqualToString:place.subtitle]) {
continue;
}
[suggestions addObject:place];
}
... // do something with suggestions
}
или в Swift:
var suggestions : [MKLocalSearchCompletion] = []
for place in results {
if place.subtitle == "Search Nearby" { continue }
resultsToReturn.add(place)
}
Мне действительно не нравится это решение, но пока оно работает для меня.
Комментарии:
1. Спасибо, я собираюсь попробовать, чтобы убедиться в этом сам! В итоге я выбрал Mapbox Search sdk, хотя он новый и находится в бета-версии. Работает, поэтому разблокирован: D
2. Джон, я думаю, я понял это. Смотрите мой ответ. Надеюсь, это поможет.