We have a setup that's really close to the one used in the example project - Monitoring location changes with Core Location.
In short, we have a flag that indicates whether or not we should start background location monitoring. If the flag is on, after the app starts, we
Create a CLServiceSession with authorization: .always
Create a CLBackgroundActivitySession
The user can perform an action (press a button) to toggle the flag off, in which case we invalidate and dispose of the CLServiceSession and CLBackgroundActivitySession instances and cancel any liveUpdates observation.
So far, so good, everything works as expected.
However, we're experiencing a weird behavior on iPhones with Dynamic Island after there's an app update.
When the user is on the same app version, the behavior is correct.
have the flag on,
background location monitoring works fine,
when the app is in the the background, there's correctly a location indicator in Dynamic Island
the user can go back to the app and turn the flag off (disposing of instances, cancelling location observation), and when the app is in the background, there is no location indicator in Dynamic Island
The problem arises when the user updates the app
open version 1.0 of the app
have the flag on,
background location monitoring works fine,
when the app is in the the background, there's correctly a location indicator in Dynamic Island
download an app update - version 2.0
the app restarts, didFinishLaunchingWithOptions gets called again and we start the background services
dynamic island indicator is correctly showing a location indicator
the user goes into the app, toggles the flag off - turning location observation off, we dispose of everything
now, when the app is moved to the background, there's still a location indicator in the Dynamic Island, even though we're no longer observing location
The indicator is hard to get rid of, there are only 2 ways we've found
restart the device, or
uninstall the app
The question is - is this a bug in the system? Or is there anything we should be doing actively after an app update?
Thank you!
Maps & Location
RSS for tagLearn how to integrate MapKit and Core Location to unlock the power of location-based features in your app.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am developing an iOS app that uses CLLocationManager to collect location continuously in both foreground and background. But it has the following 4 issues and I don’t understand why:
After a while of not using the app, I can not get location updates regularly. Even after that, I go into the app more often or even turn OFF and turn ON the permission again, but the problem still doesn’t improve until I reinstall the app.
Previously, I used SilentLog SDK to collect location. Since the cost was quite high, we developed our own SDK that also handles location tracking. After updating the app from the old version using SilentLog SDK to the new version using my own SDK, I can not get location updates regularly. However, when I reinstalled the app, it worked perfectly.
It seems that apps downloaded from TestFlight can get location more continuously than apps downloaded from the App Store
We sometimes encounter this error in the logs:
Error Domain=kCLErrorDomain Code=0 “(null)”
I think my app was not terminated in the background because I still collect location but it is not as frequent. I want to know if Apple has any mechanism to prevent such apps from getting location data continuously?
I use CLLocationManager with the following configuration:
self.locationManager.distanceFilter = 20
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.showsBackgroundLocationIndicator = false
self.locationManager.pausesLocationUpdatesAutomatically = false
I also filter the location updates using:
guard let location = locations.last else { return }
guard location.horizontalAccuracy <= 100 else { return }
guard location.speedAccuracy >= 0 else { return }
I use a background task to wake up the device every 15 minutes, and I also use silent push notifications in a similar manner. Each time the task is executed, I usually call stopLocation and then startLocation again. This happens quite frequently — will it have any impact or cause any issues?
Hello,
I'm experiencing an issue with the Apple Maps URL scheme when using raw latitude and longitude coordinates in the daddr parameter.
Until recently, using a URL like this worked reliably:
https://maps.apple.com/?daddr=37.7749,-122.4194
This would open Apple Maps and show directions from the current location to the specified coordinates.
However, on recent iOS versions, this URL no longer behaves as expected.
I am using CLLocationUpdate.liveUpdates() to build a location sharing app. Most of the time it works fine, including in the background, giving acceptably frequent updates. However, soon after the user puts their phone away for the night, the updates stop coming.
I've checked all the instance properties (.stationary, .locationUnavailable, etc.) but none of them are ever set to true, even for the last update before updates end.
Is there some way to keep the updates coming through the night?
I've included some relevant parts of my code here:
func startLocationUpdates() {
if self.manager.authorizationStatus == .notDetermined {
self.manager.requestWhenInUseAuthorization()
}
Task {
do {
self.background = CLBackgroundActivitySession()
self.session = CLServiceSession(authorization: CLServiceSession.AuthorizationRequirement.always)
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if let loc = update.location {
BackgroundServiceKt.onLocationUpdate(arg: loc)
}
// check all the instance properties
}
} catch {
// error
}
return
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
LocationsHandler.shared.startLocationUpdates()
return true
}
}
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.
Hello,
I'm encountering a runtime crash when building my visionOS app with Xcode 16.3 for visionOS 2.5. Our existing AppStore/Testflight app is also instantly crashing on visionOS 2.5 when opened but works fine on e.g visionOS 2.4.
The app builds successfully but crashes on launch with this symbol lookup error (slightly adjusted because the forum complained regarding sensitive data):
Symbol not found: _$sSo22CLLocationCoordinate2DVSE12CoreLocationMc
Referenced from: <XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX> /private/var/containers/Bundle/Application/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/MyApp.app/MyApp.debug.dylib
Expected in: <XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX> /usr/lib/swift/libswiftCoreLocation.dylib
dyld config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/usr/lib/libLogRedirect.dylib:/usr/lib/libBacktraceRecording.dylib:/usr/lib/libMainThreadChecker.dylib:/System/Library/PrivateFrameworks/GPUToolsCapture.framework/GPUToolsCapture:/usr/lib/libViewDebuggerSupport.dylib
I've already implemented my own Codable conformance for CLLocationCoordinate2D:
extension CLLocationCoordinate2D: Codable {
// implementation details...
}
This worked fine on previous visionOS/Xcode versions. Has anyone encountered this issue or found a solution?
System details:
macOS version: 15.3.2
Xcode version: 16.3
visionOS target: 2.5
Thank you!
Summary
The onLongPress callback on MapViewcomponent is not working on iOS devices. The callback is properly implemented but never gets triggered on iOS, while it works as expected on Android.
Reproducible sample code
<MapView
onLongPress={(e) => {
console.log("onLongPress", e);
setAddLocation(e.nativeEvent.coordinate);
}}
// ... other props
Steps to reproduce
Just put onLongPress callback on MapView and notice it won't be triggered.
Expected result
Long press on the map should trigger the onLongPress callback
The callback should receive the event object with coordinates
Actual result
Long press on the map does not trigger the callback on iOS
No console logs are shown when long pressing
The functionality works as expected on Android
React Native Maps Version
1.23.8
What platforms are you seeing the problem on?
iOS (Apple Maps)
React Native Version
0.79.2
What version of Expo are you using?
SDK 53
Device(s)
Any iOS Device
Topic:
App & System Services
SubTopic:
Maps & Location
We have background location updates enabled in our app that updates the location on our servers to deliver realtime weather alerts. We see that we are receiving these location updates when the app is backgrounded by the user.
However, when the user removes our app from the background using the App Switcher, we no longer see notifications happening. We have the app delegate's "didFinishLaunchingWithOptions" method setup to check for .location in the launch options, and start location tracking immediately.
Is it the intention of the OS to no longer send our app background location updates if the user manually removes our app from the background?
Topic:
App & System Services
SubTopic:
Maps & Location
Hello,
I’ve done a lot of testing of location services running in background with various settings, but in all scenarios location updates pause after a couple of hours, especially overnight In sleep mode.
My app, for personal safety, requires regular location updates to 5m accuracy every minute. The only solution I have found is to keep the app in foreground.
Location always stops updating. Background mode stops updating. Live location services stops updating.
Is there a solution I may have missed other than keeping app in foreground?
thank you,
Brendan
Is there a way to simulate altitude, longitude and latitude using the API?
For now I only found longitude and latitude to be simulated.
Topic:
App & System Services
SubTopic:
Maps & Location
In reference to this webpage, I'm turning my iPad to an iBeacon device.
class BeaconViewModel: NSObject, ObservableObject, CBPeripheralManagerDelegate {
private var peripheralManager: CBPeripheralManager?
private var beaconRegion: CLBeaconRegion?
private var beaconIdentityConstraint: CLBeaconIdentityConstraint?
//private var beaconCondition: CLBeaconIdentityCondition?
override init() {
super.init()
if let uuid = UUID(uuidString: "abc") {
beaconIdentityConstraint = CLBeaconIdentityConstraint(uuid: uuid, major: 123, minor: 456)
beaconRegion = CLBeaconRegion(beaconIdentityConstraint: beaconIdentityConstraint!, identifier: "com.example.myDeviceRegion")
peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
}
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOn:
startAdvertise()
case .poweredOff:
peripheralManager?.stopAdvertising()
default:
break
}
}
func startAdvertise() {
guard let beaconRegion = beaconRegion else { return }
let peripheralData = beaconRegion.peripheralData(withMeasuredPower: nil)
peripheralManager?.startAdvertising(((peripheralData as NSDictionary) as! [String: Any]))
}
func stopAdvertise() {
peripheralManager?.stopAdvertising()
}
}
In Line 10, I'm using CLBeaconidentityConstraint to constrain the beacon. Xcode says that this class is deprecated and suggests that we use CLBeaconIdentityCondition. But if I try to use it, Xcode says
Cannot find type 'CLBeaconIdentityCondition' in scope
I've just updated Xcode to 16.4. I still get the same error. So how do we use CLBeaconIdentityCondition to constrain the beacon? My macOS version is Sequoia 15.5. Thanks.
The other day I was playing with iBeacon and found out that CLBeaconIdentityConstraint will be deprecated after iOS 18.5. So I've written code with BeaconIdentityCondition in reference to this Apple's sample project.
import Foundation
import CoreLocation
let monitorName = "BeaconMonitor"
@MainActor
public class BeaconViewModel: ObservableObject {
private let manager: CLLocationManager
static let shared = BeaconViewModel()
public var monitor: CLMonitor?
@Published var UIRows: [String: [CLMonitor.Event]] = [:]
init() {
self.manager = CLLocationManager()
self.manager.requestWhenInUseAuthorization()
}
func startMonitoringConditions() {
Task {
print("Set up monitor")
monitor = await CLMonitor(monitorName)
await monitor!.add(getBeaconIdentityCondition(), identifier: "TestBeacon")
for identifier in await monitor!.identifiers {
guard let lastEvent = await monitor!.record(for: identifier)?.lastEvent else { continue }
UIRows[identifier] = [lastEvent]
}
for try await event in await monitor!.events {
guard let lastEvent = await monitor!.record(for: event.identifier)?.lastEvent else { continue }
if event.state == lastEvent.state {
continue
}
UIRows[event.identifier] = [event]
UIRows[event.identifier]?.append(lastEvent)
}
}
}
func updateRecords() async {
UIRows = [:]
for identifier in await monitor?.identifiers ?? [] {
guard let lastEvent = await monitor!.record(for: identifier)?.lastEvent else { continue }
UIRows[identifier] = [lastEvent]
}
}
func getBeaconIdentityCondition() -> CLMonitor.BeaconIdentityCondition {
CLMonitor.BeaconIdentityCondition(uuid: UUID(uuidString: "abc")!, major: 123, minor: 789)
}
}
It works except that my sample app can take as long as 90 seconds to see event changes. You would get an instant update with an fashion (CLBeacon and CLBeaconIdentityConstraint). Is there anything that I can do to see changes faster? Thanks.
Hi,
I'm using MapKit's MKDirections.calculate, calculateETA, and reverse geocoding (via CLGeocoder.reverseGeocodeLocation) in my iOS app.
I understand that there are undocumented rate limits for these services to prevent abuse, but I couldn't find official details.
I would like to know:
Are the rate limits applied per device, per app installation, or are they shared across all users of the same app bundle ID?
Is there any guidance on how to design these features to avoid hitting rate limits in a production environment?
What is the best practice if a user repeatedly triggers routing or reverse geocoding (e.g., typing or moving the map)?
Any clarification or official documentation would be greatly appreciated. Thank you!
I’ve just updated to Simulator 16.0 (104.1)
I’m currently developing my first app, which relies heavily on location data. It was simulating correctly before I updated Simulator. Since the update it is no longer receiving location data.
Is anyone else experiencing this problem?
Hi all,
We’re running into a challenge with our iOS app DriveSmarter, which uses background location updates when connected to a physical Bluetooth device (e.g., dash cam, radar detector). For battery efficiency, we disable location services in the background when no device is connected. The problem we’re now facing is:
How can we programmatically re-enable location services when a Bluetooth device reconnects while the app is still in the background?
From what I understand, Core Location doesn’t allow re-enabling background location updates unless the app returns to the foreground. But our core use case requires this to happen seamlessly in the background when the user starts driving and the device connects again.
To clarify:
We stop location updates when the device disconnects.
We want to resume location updates only when the device reconnects, even if the app is still in the background.
Manually bringing the app to the foreground is not a reliable or user-friendly option.
So my questions:
Is it possible to programmatically restart background location services upon a Bluetooth connection event while staying in the background?
If not, are there any best practices or Apple-recommended alternatives to achieve a similar result?
Any guidance, patterns, or creative solutions would be greatly appreciated!
Thanks in advance
The https certificate has expired
Hi,
Does anyone know how can a company sign up to be a publisher for guides on apple maps? Example - https://maps.apple.com/guides?publisher=17882075820533551969&_provider=9902
I'm having hard time figuring out the process.
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?
Could anybody give me an example how to set the „NSLocationRequireExplicitServiceSession“ in the info.plist correctly?
Thank you
Our backend management system uses Google for Location, and Apple Maps is just one of the solutions in our map component.
When should I convert coordinates to GCJ02?
Maybe you would say that when you are in mainland China?
BUT NOT AT ALL!
What if the user does not enable location permission?
What if the user has not inserted a SIM card? Or not Chinese SIM card but location in China?
OR the user location in China, But use VPN with en overseas IP?
All solutions are not perfect, unless you open the API to developers and tell us whether Apple Maps currently uses the wgs84 coordinate system or gcj02, which is the most reliable.
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
MapKit
Maps and Location
Apple Maps Server API