My app has been using MKLocalSearch.Request for keyword-based location searches, and it has worked smoothly for a long time. However, starting last Wednesday, I began receiving an error from MKLocalSearch.start: MKErrorDomain (error code 4).
This issue only occurs when the network environment is based in mainland China (where the API uses the Amap data source). When the network switches to other regions and other Apple Maps data source is used, the error does not occur.
Another complication is that the API doesn't always fail—certain keywords still work (for example, "Huawei").
Already filed a ticket in Feedback Assistant: https://feedbackassistant.apple.com/feedback/15544549
MapKit
RSS for tagDisplay map or satellite imagery from your app's interface, call out points of interest, and determine placemark information for map coordinates using MapKit.
Posts under MapKit tag
127 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
It appears that starting with macOS Sequoia, Quick Look Preview extension no longer loads MapKit maps correctly anymore. Map tiles do not appear, leaving users with a beige background.
Users report that polylines do render correctly, but annotations appears black.
This was previously working fine in prior macOS versions including Sonoma.
STEPS TO REPRODUCE
Create a macOS app project, with an associated document.
Ensure project has a Quick Look preview extension, with necessary basic setups.
Ensure that the extension mentioned in (2) must have a MKMapView. Any other cosmetic changes, etc, does not need to be implemented to observe the base issue. Do note that it has been reported that in addition to the map tiles not loading, annotations don't render correctly as well.
aoubut MKLaunchOptionsDirectionsModeKey,
when I use MKLaunchOptionsDirectionsModeTransit as a mode in my code to call function openMaps ,the apple map app launches,it has 4 mode ,subbay or ferry,bus etc,so how can I specify the subway to transit before apple map app launch,so that I do not need to select on the map app,just specific subway in my own app, then the map app auto select the subway transit navigation。now it shows two much usless route。
I am trying to listen to a podcast, but for some reason; a message keep pops up saying: This podcast can't be played due to restrictions set for this device. This happens once I installed the latest IOS. Is there any solutions for this issue?
@State var position : MapCameraPosition = .userLocation(fallback: .region(.defaultRegion))
Map(position: $position) {}
.onAppear {
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
print("check.position",position.camera,position.region,position.rect,position.item)
}
}
All of the value are nil, so how do I get the current camera position??
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
check.position nil nil nil nil
It is always nil (even if I manually move around the Map with a finger)
I’m building an iOS app using MapKit that allows users to create and navigate trails. I need offline map functionality, I was wondering if MapKit supports that. If not I was wondering if MapBox is a viable alternative to MapKit though I would prefer using MapKit. Thanks!
We are experiencing an issue where MKMapView appears red on the app builded with Xcode 16 and executed on iOS 18 simulator.
Only the ground is affected and buildings or POIs stay normal color.
Xcode 16.1 beta 3 shows same result.
Is there any similar case?
Scrolling and zooming
I have two apps that utilize the Apple Maps and since I updated my xcode to use IOS18, some of the functionalities have either been missing or glitching, and when I roll back to IOS17.5, everything seems to work fine.
When I use MKMapView and use
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
Scrolling and zooming is still not working on IOS18 but IOS17.5 works fine.
Clicking on custom annotations
When I press on a custom annotation I add to the MapView, the gesture is sometimes recognized and most of the times not recognized. If I have 20 annotations, there is a possibility only 2 of them respond to tap gestures. Below is how I define the annotation.
Annotation("Pin", coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude), anchor: .bottom) {
Button(action: {print ("Pressed annotation"){
CustomPin()
}
}
I updated my phone 14 pro to ios 18 and I faced issue with GPS. it’s show me in next Country and after minutes or hours it’s moved to the correct location
how is it can fix it
I'm using MKLocalSearch with resultTypes set to .address to search for cities. The search results don't include an ID for each city, which I need for database storage (which from my understanding is the only thing we can store).
If I can't store the city name, country, and coordinates in my database, and I'm not allowed to use third-party data (like a pre-made list of cities with coordinates), what are my options for uniquely identifying and storing these city results?
Any suggestions would be greatly appreciated.
My app uses the SwiftUI Map control to display annotations. When annotations contain buttons AND the map has an .onTapGesture modifier, annotation button taps aren’t always recognized.
Given the following ContentView, run it on an iOS device or simulator. Tap the buttons. Since iOS 18.0, some of the buttons won't respond to tap. I've also tried using the onTapGesture instead of a button, and that shows the same issue.
This was not a problem under iOS 17.x: it has only shown up for my users since updating to iOS 18. Additionally, this issue does not occur when running on either macOS 15.0 or visionOS 2.0 when running in "designed for iPad" mode.
Note that there was previously a tap issue on VisionOS 1.x (designed for iPad), where no tap gestures were received by annotations. I'm curious if this issue could be related.
I have filed a report in Feedback Assistant (FB15273909).
struct ContentView: View {
private let center = CLLocationCoordinate2D(latitude: 37.77925, longitude: -122.41924)
@State private var label: String = "tap a button"
@State private var locations: [Location] = []
var body: some View {
Map {
ForEach(locations) { location in
Annotation(location.name, coordinate: location.coordinate) {
Button(location.name) {
print("\(location.name) tapped")
label = "\(location.name) tapped"
}
.buttonStyle(.borderedProminent)
}
.annotationTitles(.hidden)
}
}
.onTapGesture { point in
print("Map tapped")
label = "map tapped"
}
.safeAreaInset(edge: .top) {
Text(label)
.padding()
.background(.thinMaterial)
.clipShape(.rect(cornerRadius: 10))
}
.navigationTitle("Test Page")
.navigationBarTitleDisplayMode(.inline)
.task {
for index in 1...16 {
locations.append(Location(name: "location \(index)",
coordinate: CLLocationCoordinate2D(latitude: center.latitude + Double.random(in: -0.02...0.02),
longitude: center.longitude + Double.random(in: -0.02...0.02))))
}
}
}
private struct Location: Identifiable {
let id: UUID = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
}
#Preview {
ContentView()
}
Hi fellow developers,
I'm encountering an issue when using MKLocalSearch to search for cities. Here's my setup:
I'm using MKLocalSearch with an MKLocalSearch.Request object.
I've set the resultTypes to .address to focus on address results.
The problem:
When I receive the search response, it includes the locations as expected. However, these locations don't have an identity or alternative identities.
Questions:
Is this the expected behavior when searching for cities?
Without an identity, how can I uniquely identify and store these city results in my database?
Would it be appropriate to store the city name, country, and coordinates instead?
Thanks in advance!
I am working on a MapView with MapAnnotation on the Map and am having difficulty getting the MapAnnotation to function properly when selected. In my code, I want the MapAnnotation selected to be to the front if it is behind or partially blocked by another annotation. I have tried using a zIndex but this does not appear to work. Below is my MapView code along with a screenshot of the issue. Any help would be greatly appreciated.
struct HospitalMapView: View {
@StateObject var viewModel = HospitalViewModel()
@State private var showSearchView = false
@State private var showListView = false
@State private var selectedTab: Int = 0
var body: some View {
ZStack {
VStack(spacing: 0) {
TopTabView()
// Map that updates the visible hospitals when the user moves or adjusts the map
Map(coordinateRegion: $viewModel.region, interactionModes: .all, annotationItems: viewModel.filteredHospitals) { hospital in
MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: hospital.latitude, longitude: hospital.longitude)) {
RoundedRectangle(cornerRadius: 40)
.fill(viewModel.colorForPercentile(viewModel.calculatePercentile(for: hospital, in: viewModel.filteredHospitals)))
.frame(width: 70, height: 30) // Maintain consistent size, adjust if necessary
.overlay(
Text("$\(Int(hospital.baseCharge / 1000))K")
.foregroundColor(.white)
.bold()
)
.overlay(
RoundedRectangle(cornerRadius: 40)
.stroke(Color.blue, lineWidth: viewModel.selectedHospital == hospital ? 3 : 0)
)
.onTapGesture {
viewModel.selectHospital(hospital)
// Move the selected hospital to the end of the list to bring it to the front
viewModel.bringHospitalToFront(hospital)
viewModel.showBottomSheet = true
}
.scaleEffect(viewModel.selectedHospital == hospital ? 1.1 : 1.0) // Highlight the selected hospital
.zIndex(viewModel.selectedHospital == hospital ? 1 : 0) // Set the zIndex higher for the selected hospital
.animation(.easeInOut, value: viewModel.selectedHospital) // Smooth transition
}
}
.onAppear {
// Initial update of visible hospitals when the map appears
viewModel.updateFilteredHospitals()
}
.onChange(of: viewModel.region) { _ in
// Update the visible hospitals as the user changes the map region
viewModel.updateFilteredHospitals()
}
.edgesIgnoringSafeArea(.all)
}
// Hospital count display hovering over the map
Text("\(viewModel.filteredHospitals.count) Hospitals")
.font(.subheadline)
.foregroundColor(.white)
.padding(8)
.background(Color.black.opacity(0.6))
.cornerRadius(10)
.padding(.top, -315) // Adjust padding to position correctly below the TopTabView
.zIndex(1) // Ensure it's above the map
if let selectedHospital = viewModel.selectedHospital, viewModel.showBottomSheet {
BottomSheetView(isOpen: $viewModel.showBottomSheet, maxHeight: UIScreen.main.bounds.height * 0.3) {
SummaryTabView(selectedHospital: Binding(
get: { selectedHospital },
set: { newValue in viewModel.selectHospital(newValue) }
))
}
.transition(.move(edge: .bottom))
.animation(.spring())
}
}
.safeAreaInset(edge: .bottom) {
BottomTabView(selectedTab: $selectedTab, showListView: $showListView, showSearchView: $showSearchView,
onSearchSelected: {
showSearchView = true
showListView = false
}, onHomeSelected: {
showSearchView = false
showListView = false
}, onListSelected: {
showListView = true
showSearchView = false
})
}
.fullScreenCover(isPresented: $showSearchView) {
SearchView(viewModel: viewModel, showSearchView: $showSearchView, selectedTab: $selectedTab, showListView: $showListView)
}
.fullScreenCover(isPresented: $showListView) {
ListView(selectedTab: $selectedTab, showListView: $showListView, showSearchView: $showSearchView)
.environmentObject(viewModel)
}
.environmentObject(viewModel)
}
}
Hello everyone -
I created a navigation app that uses a map overlay for finite spaces such as a zoo. I get these overlays created by a designer in .PNG - the designer creates the overlays and then puts a square or rectangle box around the overlay because it needs to be placed in 9 pieces making it easier to render when user zooms in/out...
I used to have my Swift devs place the overlay using the correct coordinates that were given by a single person, but we never found out exactly how they did it - and now I can no longer contact the dev.
Can anyone help me by telling me how I can get the coordinates (I am thinking that any opposite vertices would do - and maybe the center point?).
I also have a few other questions:
a. Is .SVG best to use for map overlays?
b. Should we continue to chop into 9 pieces for faster rendering or is there a better way to do this in MapKit (we have been doing this for 4 years, maybe there is a better way)
I would be so thankful for any help.
Best,
Michael
I'm trying to create a UIImage from a MKLookAroundScene, after the user has moved the scene, by looking (and moving) around. Is this possible?
When I use MKLookAroundSnapshotter with the modified scene, I always get an image of the original (starting) scene.
STEPS TO REPRODUCE
Create a scene using MKLookAroundSceneRequest with coordinates.
Use LookAroundPreview with a binding to MKLookAroundScene to get changes to the scene (based on looking around).
User begins LookAround, moving the scene location and view.
User ends LookAround
The preview displays the updated scene properly.
The scene's cameraFrameOverride values reflect the pitch, roll, yaw, and location changes.
Pass the updated scene to MKLookAroundSnapshotter to get an image.
Display the Image.
The Image is the original scene (not what is displayed in the preview).
I am trying to use MapKit JS in Tauri and Flutter desktop apps but I can‘t because if I want the key not to expire I have to whitelist a domain but my apps don't run on the web and therefore don't have a valid domain.
I have a MKMapView with a MKScaleView.
If I visualise a generic map I have the scale in km.
When I change the MKMapRect using visibleMapRect, the scale doesn't change.
If I use setVisibleMapRect(_ mapRect: MKMapRect, animated animate: Bool), the scale change but not to the correct one. For example, it shows a scale saying one inch corresponds to 250 m while it is 150 m.
The same issue of I use MKCoordinateRegion.
Instead, if I zoom in or zoom out pinching on the map, the scale updates correctly.
Am I doing something wrong? How can I fix this?
Sample code:
import UIKit
import MapKit
let CORNER_RADIUS: CGFloat = 8.0
let METERS_PER_MILE: Double = 1609.344
class PIAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
private(set) var title: String?
private(set) var subtitle: String?
init(location: CLLocationCoordinate2D,
title: String? = nil, subtitle: String? = nil) {
coordinate = location
self.title = title
self.subtitle = subtitle
}
}
class PISimpleMapView: MKMapView {
private let HALF_MAP_SIDE_MULTIPLIER: Double = 1.4
private let pinIdentifier = "pinIdentifier"
private var scaleView: MKScaleView?
typealias PinAnnotationView = MKMarkerAnnotationView // MKPinAnnotationView
required init?(coder: NSCoder) {
super.init(coder: coder)
inizialize()
}
override init(frame: CGRect) {
super.init(frame: frame)
inizialize()
}
func inizialize() {
layer.cornerRadius = CORNER_RADIUS
register(PinAnnotationView.self,
forAnnotationViewWithReuseIdentifier: pinIdentifier)
addScale()
}
private func addScale() {
let scale = MKScaleView(mapView: self)
scale.translatesAutoresizingMaskIntoConstraints = false
scale.scaleVisibility = .visible // always visible
addSubview(scale)
let guide = safeAreaLayoutGuide
NSLayoutConstraint.activate([
scale.leftAnchor.constraint(equalTo: guide.leftAnchor, constant: 16.0),
scale.rightAnchor.constraint(equalTo: guide.centerXAnchor),
scale.topAnchor.constraint(equalTo: guide.topAnchor),
scale.heightAnchor.constraint(equalToConstant: 20.0)
])
scaleView?.removeFromSuperview()
scaleView = scale
}
func displayPinOnMap(location: CLLocation) {
let annotation = PIAnnotation(location: location.coordinate,
title: "Sample", subtitle: nil)
addAnnotation(annotation)
// Position the map so that all overlays and annotations are visible on screen.
visibleMapRect = visibleArea(from: annotation)
// setVisibleMapRect(visibleArea(from: annotation), animated: true)
// region = MKCoordinateRegion(visibleArea(from: annotation))
}
private func visibleArea(from annotation: PIAnnotation) -> MKMapRect {
let annotationPoint = MKMapPoint(annotation.coordinate)
return MKMapRect(x: annotationPoint.x - HALF_MAP_SIDE_MULTIPLIER * METERS_PER_MILE,
y: annotationPoint.y - HALF_MAP_SIDE_MULTIPLIER * METERS_PER_MILE,
width: HALF_MAP_SIDE_MULTIPLIER * 2.0 * METERS_PER_MILE,
height: HALF_MAP_SIDE_MULTIPLIER * 2.0 * METERS_PER_MILE)
}
}
How to change the Type of Map to be Public Transport? I want to see a public transport map.
Thanks
I've seen a lot of posts around the internet about getting coordinates from an address, but none about how to do the opposite.
What I would like to do is allow a person to drop a pin and then programmatically look up the address closest to the pin. Like if I drop a pin inside a mall on the map I would like to capture the address to the mall.
Does anyone know how this could be done?
Hi there!
I am tying to add and select a map pin using view long press when the gesture is begin.
However after adding and selecting the pin it got deselected immediately, my assumption that it's conflicting when the original map gesture and it's deselecting the pin on the map (like if a pin was selected and you click anywhere on the map to deselect it).
Note that if I increase minimumPressDuration for the UILongPressGestureRecognizer it works fine, but I want the value at 0.5 so the pin is quickly added.
here is the full code:
import SwiftUI
import MapKit
struct ContentView: View {
@State var selection: CustomMapSelection?
@State private var longPressPosition: CGPoint = .zero
@State private var pinCoordinate: CLLocationCoordinate2D?
var body: some View {
MapReader { proxy in
Map(selection: $selection) {
if let pinCoordinate {
Marker("Custom Location", coordinate: pinCoordinate)
.tag(CustomMapSelection(coordinate: pinCoordinate))
}
}
.gesture(LongPressGestureRecognizer(position: $longPressPosition))
.onChange(of: longPressPosition) {
if let coordinate = proxy.convert(longPressPosition, from: .global) {
pinCoordinate = coordinate
selection = CustomMapSelection(coordinate: coordinate)
}
}
}
}
}
struct CustomMapSelection: Hashable {
let latitude: Double
let longitude: Double
init(coordinate: CLLocationCoordinate2D) {
latitude = coordinate.latitude
longitude = coordinate.longitude
}
}
struct LongPressGestureRecognizer: UIGestureRecognizerRepresentable {
@Binding var position: CGPoint
func makeCoordinator(converter: CoordinateSpaceConverter) -> Coordinator {
Coordinator()
}
func makeUIGestureRecognizer(context: Context) -> UILongPressGestureRecognizer {
let recognizer = UILongPressGestureRecognizer()
recognizer.delegate = context.coordinator
// if you make the minimumPressDuration above 2, it works fine and the selection doesn't cancel
recognizer.minimumPressDuration = 0.5
return recognizer
}
func handleUIGestureRecognizerAction(_ recognizer: UILongPressGestureRecognizer, context: Context) {
if recognizer.state == .began {
let position = recognizer.location(in: recognizer.view)
self.position = position
}
}
class Coordinator: NSObject, UIGestureRecognizerDelegate {
func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
) -> Bool {
return true
}
}
}
#Preview {
ContentView()
}