According to WWDC sessions, the recommended approach for continuing location collection in the background with liveUpdate is by using CLBackgroundActivitySession.
In the app I’m currently developing, I call the invalidate function on the backgroundActivitySession instance when the app enters a terminated state. Then, when the app is resurrected due to startMonitoringSignificantLocationChanges, it reinitializes liveUpdate to resume location collection. When initializing CLBackgroundActivitySession, I also reinitialize the liveUpdates object to ensure the CLLocation.Updates instance is refreshed.
However, regardless of the order in which I refresh these two instances, location collection does not resume when the app is revived in the background. Should the originally created CLBackgroundActivitySession instance never be invalidated?
Any guidance on whether I am implementing this correctly would be greatly appreciated.
Core Location
RSS for tagObtain the geographic location and orientation of a device using Core Location.
Posts under Core Location tag
127 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I have an application that uses geolocation to track the user’s location and trigger actions when the app is in either the foreground or background. Currently, it seems that region entry is not triggered unless an app like Maps (which actively uses location services) is opened. The location permissions are correctly set to “Always” with precise location enabled.
We are using geofencing to setup region and trigger actions when entering or leaving.
Is there something I’m missing in the configuration that could be preventing region monitoring from triggering properly when the app is in use or in background?
I have an App which needs to monitor one CircularGeographicCondition for a feature. No other location services are required in the moment.
Im facing the problem that entry events aren't forwarded to my implementation in every case on real devices. In the simulator everything is working like a charm. Exit events seemed to be working quite reliable on real devices too.
Even after resuming the app from background in case of a missed entry event does not trigger the entry event. Only restarting (which recreates the monitor) triggers an entry event.
The radius of my geofence is 200 meters
What I have done:
a. Holding a service session
session = CLServiceSession(authorization: .always)
b. Creating a Task which holds the CLMonitor, adds the conditions and loops through the events.
My questions are:
Is this expected behavior?
If yes, how can I force the CLMonitor to recalculate the state of the condition?
Thank you so much for your help
We have a web-based viewer which makes use of device orientation.
The permission box only appears on a “touch” and not on a swipe or pinch. Is this normal?
We’ve already tried different listeners: start, end etc but it’s still only initiated the permission request upon a physical touch / tap on screen.
Any ideas / suggestions would be gratefully received.
Many thanks in advance.
I'm attempting to use this sample code in Xcode 16 and iOS 18. I get a compile error indicating "cannot find 'CLCircularGeographicCondition'
The remainder of the sample code does not compile as in the document
the compiler wants "await" before the call to monitor.add
and another "await" before monitor.events
Is there updated sample code for this use case?
Hello.
I’m trying to use Core Location Service on any application in Mac (Safari, Maps, Weather, Chrome with Core Location configuration, or just trigger the API with a standalone app) and it seems that all of them constantly fail to provide the geolocation of my device because of the same error (kCLErrorLocationUnknown).
I'm using MacBook Pro (M3 Max) with Sonoma 14.7.
I’m sure the apps have access in the settings and everything is in order except the Core Location response.
I’ve tested the issue on multiple MacBooks and it reproduced 100% of the times on all of them.
Did anyone encounter a similar issue?
Hi everyone,
I’m encountering a strange issue with GPS tracking in my app, and I’m hoping for some insights.
I’m developing an app that records users' GPS activities (walking, biking, etc.) with app in the foreground and/or background. Most activities are outdoors, sometimes in areas with poor GPS reception, such as mountains.
To track user location, we’re using:
locationManager = CLLocationManager()
locationManager.distanceFilter = 3
locationManager.activityType = .fitness
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.allowsBackgroundLocationUpdates = true
The Issue
In certain scenarios, the GPS behaves unexpectedly.
For example (see attached image below):
A user followed a normal route (brown line), then reached an intersection and turned right (blue arrow). However, the GPS continued straight for about 200 meters (brown line) before correcting itself and resuming accurate tracking.
Here’s a snippet of the recorded coordinates during this misbehavior:
time,latitude,longitude,elevation,verticalAccuracy,horizontalAccuracy
10:17:17,47.92408,7.10438,950.82375,4.74865,4.80005
10:17:33,47.92410,7.10435,950.14966,4.74865,4.10799
10:17:44,47.92412,7.10431,943.63913,4.74865,4.46287
10:17:53,47.92413,7.10427,939.51380,4.74865,4.60644
10:17:59,47.92415,7.10424,934.82986,4.74865,4.52599
10:18:02,47.92417,7.10420,932.53145,4.74865,4.823035
10:18:05,47.92418,7.10416,927.84917,4.748655,4.59619
10:18:09,47.92420,7.10413,924.89886,4.748655,4.50172
10:18:13,47.92422,7.10409,923.35354,4.74865,4.77356
10:18:18,47.92424,7.104055,920.16327,4.74865,4.78286
10:18:22,47.92426,7.10400,915.23174,4.74865,4.66226
10:18:28,47.92427,7.10397,906.08626,4.74865,4.97331
10:18:31,47.92429,7.10394,903.25157,4.74865,4.81649
10:18:35,47.92431,7.10390,895.27948,4.74865,5.15392
10:18:38,47.92433,7.10386,889.71076,4.74865,5.25283
10:18:42,47.92435,7.10382,881.74041,4.74865,5.49089
10:18:46,47.92437,7.103785,874.34945,4.74865,5.55564
10:18:49,47.92439,7.10374,869.63184,4.74865,5.37537
10:18:53,47.92441,7.10370,861.26690,4.74865,5.39344
10:18:57,47.92443,7.10366,854.67646,4.74865,5.30404
10:19:01,47.92445,7.10362,848.48881,4.74865,5.59742
10:19:06,47.92447,7.10359,836.48915,4.74865,5.65666
10:19:08,47.92449,7.103555,835.72566,4.74865,5.54957
10:19:10,47.92450,7.10352,834.41579,4.74865,5.63540
10:19:13,47.92452,7.10348,830.17080,4.74865,5.65795
10:19:16,47.92454,7.10344,828.17052,4.74865,5.72169
10:19:19,47.92456,7.10340,824.93658,4.74865,5.62606
10:19:24,47.92458,7.10337,818.40503,4.74865,5.23265
10:19:34,47.92460,7.103335,804.42539,4.74865,4.683855
10:19:38,47.92462,7.10329,799.51747,4.74865,4.47590
10:19:48,47.92464,7.10324,784.97044,4.74865,4.59459
10:19:50,47.92466,7.10320,782.04750,4.748655,4.71036
10:19:57,47.92468,7.10317,777.49314,4.74865,4.60504
10:20:05,47.92469,7.10313,771.30168,4.74865,4.35574
10:20:09,47.92472,7.10308,766.64446,4.74865,4.94510
10:20:13,47.92474,7.10304,757.33384,4.74865,5.39175
10:20:15,47.92476,7.10300,753.52157,4.74865,5.442045
10:20:20,47.92477,7.10297,742.66179,4.74865,5.52391
10:20:23,47.92479,7.10293,735.38369,4.74865,5.44657
10:20:25,47.92480,7.10290,732.19367,4.74865,5.519945
10:20:28,47.92482,7.10286,725.15380,4.748655,5.58173
10:20:31,47.92484,7.10282,717.08813,4.74865,5.37805
10:20:34,47.92486,7.102785,710.35208,4.74865,5.27918
10:20:37,47.92488,7.10274,706.16774,4.748655,5.53270
10:20:40,47.92490,7.10270,702.84802,4.74865,5.71088
10:20:41,47.92648,7.10356,940.27115,6.600805,10.78768
10:20:43,47.92651,7.10355,940.24665,6.61807,10.45243
At 10:17:44, the location data was correct.
Shortly after, CLLocationManager started returning inaccurate coordinates. Despite the system reporting good horizontal and vertical accuracy, the altitude readings drop progressively from 940m to 702m, even though the user remained at 940m in reality. (We also recorded barometric elevation, which confirms that he stayed around 900m)
Then, at 10:20:41, the GPS corrected itself.
Questions
Is it possible that GPS could "lock onto" the wrong path, generating valid-looking but incorrect coordinates?
Can we force CLLocationManager to use GPS exclusively (disabling other sensors like Wi-Fi)? I assumed that setting activityType = .fitness would prioritize outdoor tracking, but I’m still being located indoors.
Could adjusting the activityType improve this behavior?
Could having multiple CLLocationManager() instances in our app cause issues? (We use one to save the GPS coordinates, but MapBox also creates a CLLocationManager with lower accuracy for its Telemetry framework, for example)
Thanks in advance for any help or suggestions!
Hi,
Where can I get more information on expected behaviour for the liveUpdates() configuration options, .default, .automotiveNavigation, .fitness, .automotive, .otherNavigation?
Looking for expected accuracy, frequency of updates, non/stationary transition, etc.
Thanks
Hi,
I created an iOS app compatible watchOS app which was running perfectly fine before I updated my Xcode to use iPhone16. But after updating, I started to get kclErrorDomain error: 1 and I am not sure why is it happening after update.
I am trying to use coreLocation module as-
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private var locationManager = CLLocationManager()
@Published var location: CLLocation?
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
self.location = location
print("Updated location: \(location.coordinate.latitude), \(location.coordinate.longitude)")
} else {
print("No locations received")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Failed to find user's location: \(error.localizedDescription)")
}
}
and I am trying to use it as-
@StateObject private var locationManager = LocationManager()
guard let currentLocation = locationManager.location else {
signInError = "Location not available"
isLoading = false
return
}
let latitude = currentLocation.coordinate.latitude
let longitude = currentLocation.coordinate.longitude
sendToBackend(email: email, password: password, deviceName: deviceName, deviceModel: deviceModel, deviceIdentifier: deviceIdentifier, latitude: latitude, longitude: longitude)
Can someone help me regarding this?
Hello everyone,
I’m facing an issue with my iOS app where the GPS/location services icon appears in the status bar immediately when the app is launched, even though I’m not intentionally accessing location services at that point.
Issue Summary:
• GPS Icon Activation: When I launch my app, the GPS icon turns on. It turns off when the app is minimized or closed.
• No Intentional Location Usage at Launch: I have ensured that no instances of CLLocationManager are created when the app is launched.
What I’ve Tried So Far:
1. Checked Controllers and Related Classes:
• Reviewed all the code for the controllers that are active at launch.
• Verified that none of these controllers create instances of CLLocationManager or call location-related methods.
2. Commented Out startUpdatingLocation:
• Commented out all calls to startUpdatingLocation throughout the entire project.
3. Ensured No CLLocationManager Instances at Launch:
• Searched for any code that might instantiate CLLocationManager during app launch.
• Confirmed that no such instances are being created.
4. Commented Out Google Maps SDK Configuration:
• In AppDelegate, commented out the Google Maps SDK configuration, so it’s not initialized with the API key.
• No map views (GMSMapView, MKMapView) are initialized or used when the app is launched.
5. Tested Location Permissions:
• When I change the location permission for the app to “Never” in the Settings app, the GPS icon does not appear upon app launch.
• This suggests that the app is accessing location services when it has permission, even though I haven’t explicitly requested it at launch.
Objective:
• Control GPS Activation: I want to ensure that the GPS does not turn on when the app is launched. I intend to activate location services only when needed later in the app.
Request for Assistance:
I’m seeking guidance on the following:
1. Debugging Techniques:
• How can I trace the code that’s causing the GPS to turn on at app launch?
• Are there tools or methods to identify hidden or indirect calls to location services?
2. Forcing Location Services Off at Launch:
• Is there a way to programmatically prevent location services from activating during app launch?
• Can I defer any implicit location service initialization until I explicitly enable it?
3. Potential Hidden Triggers:
• Are there known scenarios where location services could be activated without direct use of CLLocationManager?
• Could frameworks like Google Maps SDK trigger location services even if not fully initialized?
4. Additional Suggestions:
• Any other insights or suggestions to prevent the GPS icon from appearing on app launch.
Additional Information:
• Third-Party Frameworks:
• I have not removed third-party frameworks yet, as I wanted to check other possibilities first.
• Open to the idea that a third-party framework might be causing this, but need guidance on how to confirm.
• Code Availability:
• I’m happy to provide specific code snippets if that would help diagnose the issue.
Environment:
• Xcode Version: Xcode 15.4, Xcode 16.0
• iOS Deployment Target: iOS 15.0
• Devices Tested: iPhone SE 2nd and 3rd gen, iPhone 15, iPhone 15 pro, iPhone 11
• Programming Language: Swift
What I’m Looking For:
• Assistance in tracing the cause of the GPS activation on app launch.
• Suggestions on how to prevent location services from starting until explicitly needed.
• Insights into any hidden triggers or indirect usages that might cause this behavior.
Thank you for your time and assistance. Any help to resolve this issue would be greatly appreciated.
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
iOS
Debugging
Core Location
Maps and Location
This is a standalone SwiftUI app w/ watchOS 11.
To make things simple, I'm using the new concurrent API, like that:
for try await update in CLLocationUpdate.liveUpdates() { … }
watchOS is supposed to show the auth dialog, but it doesn't show up, even though update.authorizationRequestInProgress is true.
What could be the reason?
(Note that I also tried with the procedural old CLLocationManager API, it doesn't work that way as well)
In my app, I need a one-time location update, which I do with CLLocationManager’s requestLocation().
On iOS, it works fine, but on macOS Sequoia, the CLLocationManagerDelegate’s didUpdateLocations function is called indefinitely in the loop, until I call stopUpdatingLocation() on a manager. This should not be necessary unless I was calling startUpdatingLocation (which I am not), and seems like a newly introduced bug in Sequoia (or Xcode 16).
So, just a heads-up to everyone, it's necessary to call stopUpdatingLocation() after obtaining the location (or on error).
I am trying to retrieve the ellipsoidal altitude from a CLLocation but it seems like an invalid value is always returned, no matter the vertical accuracy (which according to the documentation should just be > 0) I first encountered this problem while developing a tool to retrieve workouts from healthkit, but i tried this code in a playground and i still get zero.
import CoreLocation
var location = CLLocation(coordinate: CLLocationCoordinate2D(latitude: 46.071067, longitude: 13.234579), altitude: 113, horizontalAccuracy: CLLocationAccuracy(floatLiteral: 1.0), verticalAccuracy: CLLocationAccuracy(floatLiteral: 1.0), timestamp: Date())
print(location.ellipsoidalAltitude)
Am I doing something wrong or is this a bug?
I have a solution where my application should scan the Bluetooth enabled Beacon devices in the foreground, background, locked mode for the iphone.
Currently we have built the project, which is working fine in foreground mode. We have tried exploring multiple options to enable the feature in background and locked mode.
As of now, we have come up with the solution which implements Picture in Picture mode in the application and once the application is minimized. The PIP window opens which solves our problem. But the problem stays with locked mode. The scanning is not working in locked mode.
So can we know how the bluetooth scanning will work in background and locked mode. Please also mention the alternative solutions to the problem statement if background and locked mode scanning is not possible.
I have attached the project source code for reference.
This project is being built for Google, so it is bit urgent.
Can I expect a quick response to this query?
Topic:
App & System Services
SubTopic:
Core OS
Tags:
External Accessory
Core Location
Core Bluetooth
Background Tasks
Hello, we have an app that has a case where the user can turn on a feature that starts a timer for a thing when they arrive at a specific location.
Our app also has a live activity to show the timer.
Naturally, we're trying to make our live activity to start counting when the geofence triggers, but we get ActivityAuthorizationError.visibility. If an activity is already running, it's possible to turn it off.
So, our question is basically if there's any way to make the geofence trigger start our live activity?
Thanks
Hello,
I'm trying to receive location updates on background mode but it only lasts about 10 minutes then it stops when API detected the "isStationary" is true.
Is there any way to continue receiving updates even when the device is stationary?
Btw app is not terminated by the user.
I'm using CLLocationUpdate.liveUpdates(.otherNavigation) API.
CLBackgroundActivitySession is created before calling the liveUpdates.
CLLocationManager:
let manager: CLLocationManager = {
let manager = CLLocationManager()
manager.distanceFilter = kCLDistanceFilterNone
manager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
manager.pausesLocationUpdatesAutomatically = false
manager.activityType = .other
manager.showsBackgroundLocationIndicator = true
manager.allowsBackgroundLocationUpdates = true
return manager
}()
Thank you!
We developed a app in which the I need the app to update the User's location even in background( even after terminating from the recent UI ),
Currently I am receiving the location updates when the user has kept the app in open and if minimised,
But I want that it should update the location even when it is removed from recent app (minimised UI)(after terminating the app)
Is it possible to do so.???
Topic:
App & System Services
SubTopic:
Maps & Location
Tags:
Core Location
Maps and Location
SwiftUI
Background Tasks
When I call requestWhenInUseAuthorization in state kCLAuthorizationStatusNotDetermined on iOS 18 Beta 4 in the simulator, all my apps just terminate without any error message in the Xcode console (black screen with an activity indicator for a second or two and then it goes back to the springboard). I do have the NSLocationWhenInUseUsageDescription set in my Info.plist file.
When running the exact same apps in Xcode 16.0 beta 4 (16A5211f) but with a iOS 17 simulator attached, it is working as expected by showing the location authorization dialog.
Is this a known issue or am I missing something?
I am seeing some unexpected behavior, in particular, is seems that iOS is periodically foregrounding my test app with no user intervention. I am curious why this is.
I wrote a simple test app to see how long the app would run to collect location while in the background with only "While in Use" location permission. The app will start location updates when foregrounded and continue in the background. While backgrounded, I see the blue arrow in the dynamic island as expected. What is unexpected is that every few days, I see the UI of the app displayed in the foreground, without having foregrounded it myself (and no, I did not tap the blue arrow).
This is using the legacy CoreLocation apis on iOS 17.5.1.
My question is how/why does this happen?
Hello everyone,
I'm working on a SwiftUI app that requires location services, and I've implemented a LocationManager class to handle location updates and permissions. However, I'm facing an issue where the location permission popup does not appear when the app is launched.
Here is my current implementation:
LocationManager.swift:
import CoreLocation
import SwiftUI
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var userLocation: CLLocation?
@Published var isAuthorized = false
@Published var authorizationStatus: CLAuthorizationStatus = .notDetermined
override init() {
super.init()
locationManager.delegate = self
checkAuthorizationStatus()
}
func startLocationUpdates() {
locationManager.startUpdatingLocation()
}
func stopLocationUpdates() {
locationManager.stopUpdatingLocation()
}
func requestLocationAuthorization() {
print("Requesting location authorization")
DispatchQueue.main.async {
self.locationManager.requestWhenInUseAuthorization()
}
}
private func checkAuthorizationStatus() {
print("Checking authorization status")
authorizationStatus = locationManager.authorizationStatus
print("Initial authorization status: \(authorizationStatus.rawValue)")
handleAuthorizationStatus(authorizationStatus)
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
print("Authorization status changed")
authorizationStatus = manager.authorizationStatus
print("New authorization status: \(authorizationStatus.rawValue)")
handleAuthorizationStatus(authorizationStatus)
}
private func handleAuthorizationStatus(_ status: CLAuthorizationStatus) {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
DispatchQueue.main.async {
self.isAuthorized = true
self.startLocationUpdates()
}
case .notDetermined:
requestLocationAuthorization()
case .denied, .restricted:
DispatchQueue.main.async {
self.isAuthorized = false
self.stopLocationUpdates()
print("Location access denied or restricted")
}
@unknown default:
DispatchQueue.main.async {
self.isAuthorized = false
self.stopLocationUpdates()
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
DispatchQueue.main.async {
self.userLocation = locations.last
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager error: \(error.localizedDescription)")
}
}
MapzinApp.swift:
@main
struct MapzinApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
@StateObject private var locationManager = LocationManager()
var body: some Scene {
WindowGroup {
Group {
if locationManager.authorizationStatus == .notDetermined {
Text("Determining location authorization status...")
} else if locationManager.isAuthorized {
CoordinatorView()
.environmentObject(locationManager)
} else {
Text("Location access is required to use this app. Please enable it in Settings.")
}
}
}
}
}
Log input:
Checking authorization status
Initial authorization status: 0
Requesting location authorization
Authorization status changed
New authorization status: 0
Requesting location authorization
Despite calling requestWhenInUseAuthorization() when the authorization status is .notDetermined, the permission popup never appears. Here are the specific steps I have taken:
Checked the Info.plist to ensure the necessary keys for location usage are present:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
Verified that the app's target settings include location services capabilities.
Tested on a real device to ensure it's not a simulator issue.
I'm not sure what I might be missing. Any advice or suggestions to resolve this issue would be greatly appreciated. Thank you!