I’m a bit lost on implementing a way to select a local business/place after a search and extract the phone number and name of the place. I want to do this using a sheet pop up but I’m not able to first get the map selection working. As it stands, searching does display locations on the map relevant to the original search.
import MapKit
import SwiftUI
struct MapView: View {
@StateObject private var viewModel = MapViewModel()
@State private var searchQuery = ""
@State private var phoneNumber: String? = nil
@State private var results = [IdentifiableMapItem]()
@Environment(.dismiss) var dismiss
@State private var mapSelection: MKMapItem?
var body: some View {
NavigationStack {
Map(coordinateRegion: $viewModel.region, showsUserLocation: true, annotationItems: results) { item in
MapMarker(coordinate: item.mapItem.placemark.coordinate, tint: .red)
}
.ignoresSafeArea()
.overlay(alignment: .top) {
TextField("Search for a location", text: $searchQuery)
.font(.subheadline)
.padding(12)
.shadow(radius: 10)
.textFieldStyle(.roundedBorder)
}
.onSubmit(of: .text) {
Task {
await SearchPlaces()
}
}
.onAppear {
viewModel.CheckLocationServicesEnabled()
}
}
.toolbar(.hidden, for: .tabBar)
}
func SearchPlaces() async {
let request = MKLocalSearch.Request()
request.naturalLanguageQuery = searchQuery
request.region = viewModel.region
let results = try? await MKLocalSearch(request: request).start()
self.results = results?.mapItems.map { IdentifiableMapItem(mapItem: $0) } ?? []
}
}
struct IdentifiableMapItem: Identifiable {
let id = UUID()
let mapItem: MKMapItem
}
final class MapViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 30, longitude: -122),
span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
private var locationManager: CLLocationManager?
func CheckLocationServicesEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.delegate = self
CheckLocationAuthorization()
} else {
print("turn on location alert")
}
}
private func CheckLocationAuthorization() {
guard let locationManager = locationManager else { return }
switch locationManager.authorizationStatus {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
print("put alert here for restriction parental controls or something")
case .denied:
print("alert here for when the user has already denied the app access to their location")
case .authorizedAlways, .authorizedWhenInUse:
if let location = locationManager.location {
DispatchQueue.main.async {
self.region = MKCoordinateRegion(center: location.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
}
}
@unknown default:
break
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
CheckLocationAuthorization()
}
}