I’m constructing a SwiftUI kind that ought to autocomplete road addresses the identical method Apple Maps does.
I’m utilizing MKLocalSearchCompleter, however its delegate strategies are by no means referred to as, so no ideas seem (not even in Xcode’s console). I reproduced the problem in a brand-new venture with solely the code under.
What I count on
Because the consumer varieties into the TextField, MKLocalSearchCompleter ought to name completer(_:didUpdateResults:), and deal with ideas ought to be listed under the sphere.
What really occurs
• The question string updates appropriately (verified with print).
• completer(:didUpdateResults:) and completer(:didFailWithError:) are by no means invoked.
• No ideas are proven.
Minimal reproducible instance
AddressSearchVM.swift
import SwiftUI
import MapKit
remaining class AddressSearchVM: NSObject, ObservableObject, MKLocalSearchCompleterDelegate {
@Printed var question = "" {
didSet {
// Replace the search fragment every time the consumer varieties
if question.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
completer.queryFragment = ""
outcomes = []
} else {
completer.queryFragment = question
}
print("Question modified to: (question)")
}
}
@Printed var outcomes: [MKLocalSearchCompletion] = []
non-public let completer = MKLocalSearchCompleter()
override init() {
tremendous.init()
completer.delegate = self
completer.resultTypes = [.address]
completer.pointOfInterestFilter = .excludingAll
// Broad area protecting the continental US
completer.area = MKCoordinateRegion(
middle: CLLocationCoordinate2D(latitude: 39.8283, longitude: -98.5795),
span: MKCoordinateSpan(latitudeDelta: 50.0, longitudeDelta: 60.0)
)
}
// MARK: -- MKLocalSearchCompleterDelegate
func completer(_ completer: MKLocalSearchCompleter,
didUpdateResults outcomes: [MKLocalSearchCompletion]) {
print("Acquired outcomes: (outcomes.map { $0.title })")
DispatchQueue.fundamental.async {
self.outcomes = Array(outcomes.prefix(5))
}
}
func completer(_ completer: MKLocalSearchCompleter,
didFailWithError error: Error) {
print("Autocomplete error: (error.localizedDescription)")
DispatchQueue.fundamental.async {
self.outcomes = []
}
}
// MARK: -- Helpers
func clearResults() {
outcomes = []
question = ""
}
}
ContentView.swift (related half)
struct ContentView: View {
@StateObject non-public var addressVM = AddressSearchVM()
@FocusState non-public var focus: Discipline?
@State non-public var showingSuggestions = false
@State non-public var pickupAddress = ""
enum Discipline { case deal with }
var physique: some View {
Kind {
Part("Pickup Deal with") {
HStack {
Picture(systemName: "mappin.and.ellipse")
.foregroundColor(.secondary)
TextField("123 Instance St", textual content: $addressVM.question)
.centered($focus, equals: .deal with)
.onChange(of: addressVM.question) { _, newValue in
showingSuggestions = !newValue.isEmpty && focus == .deal with
if newValue.isEmpty { pickupAddress = "" }
}
.onChange(of: focus) { _, newFocus in
showingSuggestions = newFocus == .deal with && !addressVM.question.isEmpty
}
}
if showingSuggestions && !addressVM.outcomes.isEmpty {
VStack(alignment: .main, spacing: 0) {
ForEach(addressVM.outcomes, id: .self) { merchandise in
Button {
let full = merchandise.title + (merchandise.subtitle.isEmpty ? "" : ", (merchandise.subtitle)")
pickupAddress = full
addressVM.question = full
showingSuggestions = false
focus = nil
} label: {
VStack(alignment: .main, spacing: 2) {
Textual content(merchandise.title)
if !merchandise.subtitle.isEmpty {
Textual content(merchandise.subtitle).font(.caption).foregroundColor(.secondary)
}
}
.padding(.vertical, 8)
.body(maxWidth: .infinity, alignment: .main)
}
.buttonStyle(.plain)
if merchandise != addressVM.outcomes.final { Divider() }
}
}
}
}
}
}
}
Issues I’ve tried
- 1.New clean venture with solely this code → similar habits.
- Completely different simulators (iPhone 14 / 15) and an actual system → no change.
- Commented out the customized area (let Apple select default) → no change.
- Added specific calls to startUpdatingLocation() by way of CLLocationManager to verify location companies have been energetic → nonetheless no delegate callbacks.
Any perception or workaround could be drastically appreciated.
Thanks upfront!