Maps & Location

RSS for tag

Learn how to integrate MapKit and Core Location to unlock the power of location-based features in your app.

Maps & Location Documentation

Posts under Maps & Location subtopic

Post

Replies

Boosts

Views

Activity

Granularity/Accuracy of delivered locations with live updates
First of all : Thanks for the great presentation (wwdc2023-10180), Siraj ! This new, simple API looks like what we've been looking for for easy manageable background location updates with 'automatic battery drain minimization' :-) There were two questions that came to my mind. As far as I understood, the CLLocationUpdate.LiveConfiguration is used to help the location services to improve the location fixes. Are there other options planned to specify the granularity of delivered locations e.g., how accurate the locations need to be (as the desiredAccuracy and distanceFilter settings for the olden CLLocationManager)? Does the Implementation switch between significant location changes and regular, more expensive ways (like GPS hardware) or just deliver the most feasible accuracy available at the time of notification? I'm just curious - if I get the most feasible granularity, everything is fine for me anyway :-) Thanks again, Michael
2
0
994
Jan ’25
can not find placemark when search by japanese character
when I using MKLocalSearch by japanese character let request = MKLocalSearch.Request() request.naturalLanguageQuery = "東京涩谷地下鉄駅" request.region = mapView.region let search = MKLocalSearch(request: request) search.start {....} ,it can not return the placemark, shows Error : The operation couldn’t be completed. (MKErrorDomain error 4.). Failed to parse font key token: hiraginosans-w6 how can I fix this problem,thankyou! import UIKit import MapKit class ViewController: UIViewController, MKMapViewDelegate { @IBOutlet weak var resultsTableView: UITableView! var mapView: MKMapView! var searchResults = [MKMapItem]() override func viewDidLoad() { super.viewDidLoad() mapView = MKMapView(frame: CGRect(x: 0, y: 220, width: view.bounds.width, height: view.bounds.height - (tabBarController?.tabBar.frame.size.height ?? 0))) mapView.showsScale = true mapView.showsCompass = true mapView.showsScale = true mapView.showsUserLocation = true mapView.userTrackingMode = .follow mapView.delegate = self view.addSubview(mapView) let selectedCoordinate = CLLocationCoordinate2D(latitude: 35.661777, longitude: 139.704051) // some Coordinate near 東京涩谷地下鉄駅 let selectedLocation = CLLocation(latitude: selectedCoordinate.latitude, longitude: selectedCoordinate.longitude) let coordinateMKCoordinateRegion = MKCoordinateRegion(center: selectedLocation.coordinate, latitudinalMeters: 50000, longitudinalMeters:50000) mapView.setCenter( selectedLocation.coordinate, animated: true) mapView.setRegion(coordinateMKCoordinateRegion, animated: true) drawCircle(radius: 5000, center: selectedLocation.coordinate) searchForStation() } func drawCircle(radius: CLLocationDistance, center: CLLocationCoordinate2D) { let circle = MKCircle(center: center, radius: radius) mapView.addOverlay(circle) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { if let circleOverlay = overlay as? MKCircle { let circleRenderer = MKCircleRenderer(circle: circleOverlay) circleRenderer.fillColor = nil circleRenderer.strokeColor = UIColor.blue circleRenderer.lineWidth = 2.0 return circleRenderer } return MKOverlayRenderer(overlay: overlay) } func searchForStation() { print( "searchForStation" ) let request = MKLocalSearch.Request() request.naturalLanguageQuery = "東京涩谷地下鉄駅" // request.region = mapView.region let search = MKLocalSearch(request: request) search.start { [weak self] (response, error) in guard let self = self else { return } guard let response = response, let mapItem = response.mapItems.first else { print("Error : \(error?.localizedDescription ?? "Unknown error").") return } for mapItem in response.mapItems { print( "mapItem.placemark =",mapItem.placemark) // hope to get 東京涩谷地下鉄駅placemark,the value of latitudeand longitude) } } } }
2
0
418
Oct ’24
"Compiler failed to build request" Spam when using MKTileOverlay
I'm building a weather map that shows the rain on the map. I'm able to retrieve PNG images that are used as tiles to put onto the map. I then reload all the tiles on the map with each timeframe (tile set for every 10 minutes). I'm able to get the map loaded up and I'm able to place the tiles and reload the data for each time slot. But I'm getting a ton of spam on the console every time the tiles are reloaded. Failed to locate resource named "sky20Grey0@2x.png" Failed to locate resource named "sky20Grey0@2x.png" Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Compiler failed to build request Yet the images are showing on the map just fine. But I feel like it's a bit sluggish due to all the spam coming out as I'm reloading this every 0.5 seconds with a timer. I've tried to load the data from a remote server on demand by overriding the - (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result function. But due to the timer this can lead to the data not getting loaded fully before it switches to the next time slot of data. I therefore pre-load everything. I can then store the NSData in memory and use loadTileAtPath or the NSURL to a stored file and use - (NSURL *)URLForTilePath:(MKTileOverlayPath)path. Both cases work. But both cases have this spam. I've further refined things such that the MKTileOverlayRenderer is reused but that didn't help. Here's the function for that.. - (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay { if ([overlay isKindOfClass:[MKTileOverlay class]]) { if (!self.rainRenderer) { self.rainRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay]; self.rainRenderer.alpha = 0.5; } return self.rainRenderer; } return nil; } I'm using one MKOverlay and then just reloading the tiles as needed. Otherwise there is quite a pronounced flicker. Here's that function which is triggered by the NSTimer to happen every 0.5 seconds. - (void) updateRainFrame { self.currentFrameIndex = (self.currentFrameIndex + 1) % self.timestamps.count; if ((self.currentFrameIndex >= 0) && (self.timestamps.count > self.currentFrameIndex)) { NSLog (@"self.currentFrameIndex = %lu", self.currentFrameIndex); NSString *timestamp = self.timestamps[self.currentFrameIndex]; [self.overlay setTimestamp:timestamp]; [self.rainRenderer reloadData]; } } In that function I'm updating the "timestamp" in the overlay which is the time slot that contains all the tiles for that time. This way my overridden MKTileOverlay can then pass the correct path for the tiles. For example for loading from a file: - (NSURL *)URLForTilePath:(MKTileOverlayPath)path { return [self getWeatherTileFileURLForPath:path]; } Or NSData stored in memory - (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result { return [self getWeatherTileDataForPath:path]; } But no matter which way I use I keep getting this spam and unfortunately there is no error or anything to point to why it is spamming out. Also the tiles themselves are PNG files either 256x256 or 512x512 in pixel size. I saw that this could be something to do with Metal but I'm assuming that's something that MapKit uses. Very much welcome any thoughts to what could be causing this?
2
0
89
Jun ’25
MapKit with MKTileOverlay Crashes After a Time
I'm building a weather map that shows the rain on the map. I'm able to retrieve PNG images that are used as tiles to put onto the map. I then reload all the tiles on the map with each timeframe (tile set for every 10 minutes). I'm able to get the map loaded up and I'm able to place the tiles and reload the data for each time slot. I preload all the PNG data needed for the tiles and store that NSData for them in memory so that they are quick for loading and showing on the map. I have timer's set to reload the overlay with the next set of tiles for each time slot. Giving the view of a moving precipitation map over time (just like you'd see on any weather map.) I have 12 time slots (timestamps) showing every 10 minutes for the past 2 hours. I have it showing each in sequence and then repeating. Over time I get a crash with this error as a Thread 1: signal SIGABRT. Failed to acquire drawable, rendering to temporary texture validateRenderPassDescriptor:782: failed assertion `RenderPass Descriptor Validation MTLRenderPassAttachmentDescriptor MTLStoreActionMultisampleResolve store action at attachment 0 requires resolve texture ' validateRenderPassDescriptor:782: failed assertion `RenderPass Descriptor Validation MTLRenderPassAttachmentDescriptor MTLStoreActionMultisampleResolve store action at attachment 0 requires resolve texture ' Through some searching I've discovered that this seems to be console output from Metal. I assume Metal is used for MapKit to render the overlay tiles? I'm using the same custom overlay where I set the timestamp on it and then tell it to reload. I also reuse the same MKOverlayRenderer as shown here... - (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay { if ([overlay isKindOfClass:[MKTileOverlay class]]) { if (!self.rainRenderer) { self.rainRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay]; self.rainRenderer.alpha = 0.5; } return self.rainRenderer; } return nil; } And here's the function that reloads the overlay... - (void) updateRainFrame { self.currentFrameIndex = (self.currentFrameIndex + 1) % self.timestamps.count; if ((self.currentFrameIndex >= 0) && (self.timestamps.count > self.currentFrameIndex)) { NSLog (@"self.currentFrameIndex = %lu", self.currentFrameIndex); NSString *timestamp = self.timestamps[self.currentFrameIndex]; [self.overlay setTimestamp:timestamp]; [self.rainRenderer reloadData]; } } The time it takes to crash seems arbitrary. Sometimes it's very quick. Less than a minute. But usually it's several minutes. 10 or 20 minutes or more. Feels like some sort of race condition that's occurring. Perhaps ARC is not able to release the images for the tiles quick enough for each overlay reload? That's a wild guess but I think it's something more deeper in Metal as I feel I would see other errors related to memory availability. Some of my searches point to something about MSAA needing to be turned off in Metal to resolve this. However I have no idea how I would do that through MapKit. Any suggestions? Let me know if there is somehow a way to capture more from the crash to give more insight.
2
0
95
Jun ’25
Request to Add an “AllowOnce” State to CLLocationManager
Context: Currently in iOS, both “Allow Once” and “While Using the App” location permission decisions yield .authorizedWhenInUse. This conflation prevents apps from knowing whether the user has provided a one-time allowance or a persistent in-use allowance. Problem Statement Ambiguous App Behavior: After a user selects “Allow Once,” the app remains in .authorizedWhenInUse, making it appear to the developer as if the user granted a more persistent “While Using” permission. Poor User Experience: If the user later indicates they want to upgrade to “Always,” developers must guess whether iOS will show another system prompt. This can lead to “dead” button presses or pointless transitions to Settings. Lack of Transparency: The user’s real intention—“I only trust you this one time”—gets lost in .authorizedWhenInUse with no direct or synchronous detection mechanism. Why This Wouldn’t Violate SRP The CLLocationManager’s` Single Responsibility: Manage and expose the user’s current location authorization state. Adding .authorizedOneTime or an isOneTime property fits neatly into that responsibility. It’s still describing the user’s level of trust for location usage, just with more specificity. No Overreach: This doesn’t add new logic outside location permissions—it merely refines the existing state definitions for clarity. Simplifies the Developer Flow: Instead of co-mingling “Allow Once” and “While Using,” the system returns the precise state, letting developers handle transitions more gracefully while abiding by iOS’s privacy rules. Benefits Improved UX: Developers can present more accurate prompts or guidance. If .authorizedOneTime, the app can immediately direct the user to Settings for a persistent upgrade, rather than futilely calling requestAlwaysAuthorization() again. Less Confusion: A distinctly reported “Allow Once” state eliminates guesswork, polling, or timed approaches that degrade user experience. Consistent with iOS’s Privacy Focus: Providing a read-only flag or status for “One Time” aligns with Apple’s approach to clarity around permissions, without letting apps forcibly bypass user intentions.
2
1
383
Jan ’25
Request of CarPlay Navigation Entitlement when having the Driving Task one
I have the CarPlay Entitlement "Driving Task" and two of my apps use it. Now, in both apps, I have implemented Navigation. I requested the Navigation CarPlay Entitlement when the feature was mature and builds were available in Test Flight, since I wanted to release the new versions of the apps with navigation available both on the iPhone and in CarPlay. I got no answer to my request, so I decided to release the apps with only navigation in the iPhone and the Driving Task functionality in CarPlay, thinking that maybe being live with navigation in the App Store was a requirement. I have asked permission again, and so far, the request is being ignored again. What are the requirements to get the Navigation CarPlay Entitlement? If the app is approved for navigation, is there something else the app must do to get the entitlement? Requirements for CarPlay Entitlements seem quite obscure, are they listed anywhere? Is there a technical problem to move from an existing CarPlay Entitlement to another? Can that be the reason the entitlement has not been granted? Some of my competitors have the CarPlay Navigation entitlement. My use case is the same (in a better app in my opinion, of course). But I am only getting bad reviews because "the app does not include the map in CarPlay" after the big investment in implementing navigation in the apps. Any help or insight would be appreciated.
2
0
785
May ’25
Details on CLBackgroundActivitySession and CLServiceSession Diagnostic enum
I am working with the CLBackgroundActivitySession and CLServiceSession to figure out why our app is sometimes terminated in the background. I am unable to understand what "insufficientlyInUse" corresponds to, it could be understood as The location data is not being used enough the "While in use" permission is not enough It will be very helpful if the entire enum can be explained, I am attaching the one for CLServiceSession since it is a superset of CLBackgroundActivitySession from CoreLocation extension CLServiceSession { public struct Diagnostic { public var authorizationDenied: Bool { get } public var authorizationDeniedGlobally: Bool { get } public var authorizationRestricted: Bool { get } public var insufficientlyInUse: Bool { get } public var fullAccuracyDenied: Bool { get } public var alwaysAuthorizationDenied: Bool { get } public var serviceSessionRequired: Bool { get } public var authorizationRequestInProgress: Bool { get } } ... } Looking forward to hearing from you
2
0
598
Nov ’24
How to Handle Periodic Background Location Reminders for an MDM-Managed Safety App?
Hello everyone, We've developed a safety application for schools that runs on supervised, MDM-managed iOS devices. The app requires "Location Always" to maintain a persistent background state for its core functionality. The Challenge: Our primary issue is with the periodic background location reminder prompts that iOS automatically presents to the user (e.g., "[App Name] has used your location X times in the past 3 days..."). A screenshot of the exact prompt is attached. While we educate users on the importance of selecting "Always Allow," these recurring prompts make it very easy for a student to downgrade the permission at a later date, which disables the app's safety features. This makes the solution unreliable in a school environment. Our Question: Since these are supervised devices managed by an educational institution, we are looking for a way to manage this behavior. Is there any Info.plist key, entitlement, or API available to developers to influence or suppress these recurring location reminders for our app? From an MDM perspective, is there a known payload or declarative management configuration that can prevent these specific prompts from appearing for a designated app? We understand these prompts are a key privacy feature. Our question is whether there are any provisions for managed, special-purpose environments like a school, where the app's function is considered essential and pre-approved by the device administrator (the school). We are looking for a way to provide a "set it and forget it" configuration for the school, but these reminders currently prevent that. Any architectural advice or insights would be greatly appreciated. Thank you.
2
0
95
Jul ’25
CLBackgroundActivitySession Crash Issue - Misleading Apple Guidance
I encountered a crash in iOS 17 related to CLBackgroundActivitySession, which appears to be due to misleading guidance in an Apple’s WWDC video. Crash sample code: https://github.com/steve-ham/AppleLocationCrash Simplified Reproduction Steps: 1. Open the GitHub sample app. 2. Archive and export (Distribute App -> Custom -> (Release Testing, Enterprise, or Debugging) -> Export). 3. Open the app. 4. Tap enableBackgroundLocation -> select Allow While Using App on the system popup. 5. Tap disableBackgroundLocation. 6. Go to the iOS home screen. 7. Wait for 10 seconds. 8. Reopen the app -> crash occurs. The crash happens because setting CLBackgroundActivitySession to nil does not end the session, despite Apple’s guidance suggesting it should. Below is the exact quote from WWDC 2023, which explicitly states that both calling invalidate() or letting the object get destroyed (i.e., setting to nil) would end the session: WWDC 2023 Discover Streamlined Location Updates (https://developer.apple.com/videos/play/wwdc2023/10180/) “Before starting the updates, you should instantiate a CLBackgroundActivitySession object to start a new session. Note, we are assigning the session to self.backgroundActivity, which is a property and not to a local variable. And this is important because if we used a local variable, then when it goes out of scope, the object it holds would be deallocated, invalidating the session and potentially ending your app’s access to location. Then when we want to end our session, we can do that by sending the invalidate message or by letting the object be destroyed.” I’ve submitted this to Apple for resolution but wanted to share this with the community. This misguidance has caused issues in my app’s release. If Apple could reply to confirm or provide clarification, it would be greatly appreciated. P.S. Even a minimal implementation in viewDidLoad triggers the crash: let session = CLBackgroundActivitySession() print("session (session)")
2
0
758
Nov ’24
Using Maps in App Intents
I want to use MapKit with App Intents, but the map does not show up.(See attached image) Can anyone help me solve this? import SwiftUI import MapKit struct ContentView: View {   @State private var region = MKCoordinateRegion(     center: CLLocationCoordinate2D(latitude: 37.334_900,                     longitude: -122.009_020),     latitudinalMeters: 750,     longitudinalMeters: 750   )       var body: some View {     VStack {       Map(coordinateRegion: $region).frame(width:300, height:300)         .disabled(true)     }   } } struct ContentView_Previews: PreviewProvider {   static var previews: some View {     ContentView()   } } import AppIntents import SwiftUI import MapKit struct test20220727bAppIntentsExtension: AppIntent {   static var title: LocalizedStringResource = "test20220727bAppIntentsExtension"       func perform() async throws -> some IntentResult {     return .result(value: "aaa", view: ContentView())   } } struct testShortcuts:AppShortcutsProvider{   @available(iOS 16.0, *)   static var appShortcuts: [AppShortcut]{     AppShortcut(       intent: test20220727bAppIntentsExtension(),       phrases: ["test20220727bAppIntentsExtension" ]     )   } }
2
0
1.2k
Mar ’25
iOS 18: startRangingBeacons Stops When Display is Off in Background (Worked on iOS 17.2.1)
Issue Summary After calling startRangingBeacons, the didRangeBeacons delegate method does not receive iBeacon scan data when the device display is turned off in the background. Expected Behavior On iOS 17.2.1 (iPhone 14), beacon ranging continues in the background even when the display is turned off. The same behavior is expected on iOS 18, but it is not working as intended. Observed Behavior On iOS 18, once the display turns off, beacon ranging stops, and the didRangeBeacons method is not triggered until the display is turned back on. • Location permission is set to “Always Allow.” • Background Modes are correctly configured (Location Updates enabled). Steps to Reproduce Ensure location permission is set to Always Allow. Enable Background Modes → Location Updates in Xcode settings. Call startRangingBeacons(in:) in the app. Put the app in the background and turn off the display. Observe that didRangeBeacons is not triggered while the display is off. Additional Notes • The issue does not occur on iOS 17.2.1 (iPhone 14), where beacon ranging continues even with the display off. • This behavior change is observed on iOS 18 across multiple devices. Could you confirm if this is an intended change in behavior or a bug? If this is expected behavior, what alternative approach is recommended to maintain continuous beacon ranging when the display is off in the background?
2
0
458
Feb ’25
Checking Wi-Fi Status for Location Accuracy in iOS App
I am working on a duress app and would like to improve location accuracy by encouraging users to enable Wi-Fi. In Apple Maps, I noticed that when Wi-Fi is off, a dialog prompts users to turn on Wi-Fi to enhance location accuracy. I am looking to implement similar functionality in my app. Specifically, I would like to check whether Wi-Fi is enabled on the user's device (even if it is not connected to a network). Despite exploring several methods, I have been unable to determine a reliable way to check the Wi-Fi status. Can you guide me on whether it is possible to access this functionality in iOS, and if so, how I can implement it within my app?
2
0
433
Feb ’25
Bluetooth permissions Query
Hi Team, when our customers turn on bluetooth connectivity whether Apple creates a profile of the user or their locations and if it is used for any other purpose. Could you please clarify this? we are getting the below message in the Bluetooth permissions popup below the map "Information from Bluetooth devices can be used to determine your location and create a profile of you." What is this profile? and what is the purpose of creating it while the user uses Bluetooth in ios app.
2
0
64
Aug ’25
MapKit JS Look Around not pointing camera towards the lat/lng entered
We are using MapKit JS Look Around and initializing it like this: window.lookAround = new mapkit.LookAround( document.getElementById('container'), new mapkit.Coordinate(listingLocation[1], listingLocation[0]), {openDialog: false}) ; This results in a Look Around scene being displayed correctly but the camera heading is not pointing towards the lat/lng that is passed to initialization. The example lat/lng that we're using is: lat=30.004195, lng=-95.59973 This lat/lng corresponds to the address: 11943 Laurel Meadow Dr, Tomball, TX 77377. The camera is pointing to the other side of the street to house number 11946. If you look for that address in Apple Maps the Look Around points to the correct house. Is there a way to either specify the heading so that Look Around points in the correct heading? Sample link: https://s.hartech.io/zFP2KnsCbsP
2
0
66
2d