Core Location

RSS for tag

Obtain the geographic location and orientation of a device using Core Location.

Posts under Core Location tag

111 Posts

Post

Replies

Boosts

Views

Activity

Watch-Phone communication when Phone app is in background
There doesn't seem to be a background mode that will allow an iPhone app to run in the background in order to communicate with its watch app, which is running in the foreground on the watch. Have I missed something? Related but not quite the same: say the iPhone app can run in the background to get location updates. But it only wants to do so when the watch app is running. Is there a way that the watch app can wake, or even start, the iPhone app, and for the iPhone app to then enable location updates? (I have previously implemented Bluetooth background modes - I think I could achieve both of the above if I had the watch and the iPhone communicate using my own BTLE protocol, rather than using Watch Connectivity. Is this true?)
6
0
864
Feb ’25
Background location tracking on iPad fails
My app needs to track background location for a period of several hours while the user is using it, and we want to allow the user to switch apps or lock their phone while this is happening. We don't need to track location permanently and because of this, we don't want to request the "Always allow" permission. The app requests "While in use" permission and it has the "Location updates" background mode enabled. The CLLocationManager has 'allowsBackgroundLocationUpdates' set to true, 'pausesLocationUpdatesAutomatically' false, kCLLocationAccuracyBest, kCLDistanceFilterNone, and .fitness for the activity type (we expect the user to be walking). The app also initializes a CLBackgroundActivitySession while it is tracking location and invalidates it when done. When I test this combination on my iPhone, it works fine. I get location tracking in the background for as long as I need it, regardless of what else I do with the phone. However, my customer says it doesn't work for him. He is using a Wifi-only iPad with an external GPS receiver called "BadElf GPS Pro". He says that the external GPS receiver works fine with other apps on his iPad. With my app, he gets background location tracking only for a short time, and then it stops. The app does monitor the "locationManagerDidPauseLocationUpdates" callback and posts a local notification if it gets called, but it doesn't get called. I've also confirmed with him that he is not force-quitting the app and the app is not otherwise being terminated by iOS. Is there something I'm missing?
3
0
579
Feb ’25
iOS location recording issues iOS 18
I’m facing an issue with iOS that I hope someone can help with. I developed an app a few years ago that records GPS tracks. Up until recently, everything worked fine—even when the app was running in the background, the recording continued without problems. However, since releasing an update compiled after the iOS 18 release, users have reported that background tracking no longer works. I’ve reviewed the iOS documentation but haven’t found any relevant changes or solutions. Before the newly compiled release the app was working well on iOS 18 devices as well. Some users have reported that switching to the location permission from "When Using the App" to "Always" solved the issue. This is not the case for all users. Has anyone else encountered this issue? Any recommendations or insights on how to resolve it would be greatly appreciated. Below you can see the code used for the location tracking. Before the issue happened the app was compiled with XCode 15.4. Now I am using XCode 16.2 locationManager.activityType = CLActivityType.fitness locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.distanceFilter = 3 locationManager.allowsBackgroundLocationUpdates = true locationManager.pausesLocationUpdatesAutomatically = false if #available(iOS 11.0, *) { locationManager.showsBackgroundLocationIndicator = true } locationManager.startUpdatingLocation() if #available(iOS 17.0, *) { // Create a CLBackgroundActivitySession object backgroundActivitySession = CLBackgroundActivitySession() } Thanks in advance for your help!
3
2
606
Feb ’25
Background location tracking not reliable
I'm writing an app in which the user is expected to initiate location tracking, let the app track for a period of time (a few minutes to a couple of hours) and then discontinue tracking. We want the user to be able to switch apps or let their device lock while tracking without losing any location updates. My understanding is that this can be done with the "While in use" location permission and does not require "Always". We don't want to have to ask our users for the "Always" permission. I'm configuring the location manager this way: locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation locationManager.allowsBackgroundLocationUpdates = true locationManager.showsBackgroundLocationIndicator = true locationManager.distanceFilter = kCLDistanceFilterNone locationManager.activityType = .otherNavigation locationManager.pausesLocationUpdatesAutomatically = false (The user is expected to be walking around in an outdoor location, stopping occasionally to take notes and pictures). I've tested this using both an iPhone and an iPad that relies on an external GPS device. It works. I can lock the device and see a continuous stream of location updates in the debugger for hours. I've also tested it while walking outdoors. However, my customer keeps reporting that the app stops tracking his location whenever it goes into the background. He says that it will track his location fine while in the foreground, but when he backgrounds it, it stops getting location updates. Then when it comes into the foreground again, it resumes. When we plot the locations on a map, you see a straight line between the place where the app went into background and where it woke up again. We know for sure that the app is just transitioning to and from the background and that it is not being terminated and restarted. I can't reproduce this result on my devices and can't figure out what I'm doing wrong. The customer says he has another app on his device (which is also an iPad with an external GPS) and that the other app does track him when it is in the background. My app does process all of the locations received in the didUpdateLocations method and not just the last one, so it's not that I'm getting the updates and ignoring them. I'm also not receiving any calls to 'locationManagerDidPauseLocationUpdates', 'didFinishDeferredUpdatesWithError', or 'didFailWithError'. The only explanation I can think of at the moment is that something changed in iOS. I know that the other app my customer is using is fairly old and built against an old version of the iOS SDK. Thanks for your help.
1
1
414
Jan ’25
iOS 18: “Settings” button on location permission alert does nothing, logs BUG IN CLIENT OF UIKIT warning
Hello everyone, I’m encountering a problem on the latest iOS 18 related to location permissions. When the user denies location access, my app triggers the standard system prompt asking them to enable location from Settings. On iOS 17 and below, tapping the “Settings” button in this system alert would successfully navigate the user to my app’s Settings page. However, on iOS 18, nothing happens. Instead, I see the following warning in the Xcode console: Warning : BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(:) needs to migrate to the non-deprecated UIApplication.open(:options:completionHandler:). Force returning false (NO). Important details and context: In my own code, I have already replaced all calls to openURL(:) with open(:options:completionHandler:). I searched the entire codebase for usage of openURL: and didn’t find any. The alert that appears is the system location alert (iOS-generated), not a custom UIAlertController. Thus, I have no direct control over the underlying call. On iOS 17 (and below), tapping “Settings” in the same system dialog works perfectly and takes the user to the app’s permission page. The console message implies that somewhere—likely inside the system’s own flow—the deprecated API is being called and blocked on iOS 18. What I’ve tried: Verified I am not calling openURL: anywhere in my code. Confirmed that UIApplication.openSettingsURLString works when I programmatically open it in a custom alert. Tested multiple times on iOS 17 and iOS 18 to confirm the behavior difference. Steps to reproduce: Install the app on a device running iOS 18 Beta. Deny location permission when prompted. Trigger a piece of code that relies on location (e.g., loading a map screen) so that the OS automatically shows its standard “Location is disabled” alert, which includes a “Settings” button. Tap “Settings.” On iOS 17, this navigates to the app’s Settings. On iOS 18 Beta, it does nothing, and the console logs the BUG IN CLIENT OF UIKIT warning. Questions: Is this a known iOS 18 bug where the system’s own alert is still using the deprecated openURL: call? If so, are there any workarounds besides presenting a custom alert that manually calls open(_:options:completionHandler:)? Thank you in advance. Any guidance or confirmation would be appreciated!
1
1
969
Jan ’25
How to Reduce Geolocation Drifting Inside Buildings on iOS?
I am developing a Flutter app that uses geolocation data extensively. While the location accuracy is excellent under an open sky, I’ve noticed significant drifting when users are inside large buildings. This impacts the app’s functionality as precise location data is critical. I would like to know: Are there any specific configurations or APIs available in the Apple ecosystem to enhance indoor geolocation accuracy? Would combining GPS with other location technologies (like Wi-Fi or Bluetooth) reduce drifting effectively? Are there recommended practices for handling geolocation indoors on iOS? Any advice, examples, or guidance would be greatly appreciated!
1
0
347
Jan ’25
It's not possible to access system PTT UI when app is backgrounded and "Always" location access is activated for app
Hello. Our app uses PTT framework and "Always" location tracking at the same time. By some reason, after backgrounding app, Dynamic Island shows only location tracking icon instead if PTT icon. And when user taps on it - application foregrounding instead of system PTT UI show. Only after first incoming PTT user can access system PTT UI. Is it a bug or intended behaviour?
1
0
409
Jan ’25
New CoreLocation APIs
Hi All, I am currently working on an app that has some navigation functionality, and since my minimum iOS is 18 wanted to incorporate the new APIs that yield a AsyncStream of locations. I have watched both WWDC sessions, the one where the new API is introduced to retrieve the location points, and also the other video where the new authorization process for location is simplified as well. I have an app currently working in its current state, but am noticing some weird quirks when using the CLBackgroundActivitySession to get the elevated background permission. What I am doing here is to create this stream and the background object is below: return AsyncThrowingStream { continuation in let task = Task { do { for try await update in CLLocationUpdate.liveUpdates(updateType) { if shouldStopUpdate { continuation.finish() break } continuation.yield(update) } } catch { continuation.finish(throwing: error) } } state = .started(locationTask: task, background: CLBackgroundActivitySession()) } When I have an active navigation session going and am strongly holding this object and the user force quits the app (or I stop the target through Xcode) the navigation activity indicator in the status bar (or dynamic island) remains present. Even if I relaunch the app, start navigation again, and then call the invalidate method on the CLBackgroundActivitySession I then am seeing that navigation indicator even if I delete my app, and often need to do a full restart to get out of this state. Is there a step I am missing, or do I not understand the way the new API works to run in the background?
1
0
622
Jan ’25
The latest IOS doesn't act for the custom iBeacon anymore.
I have some questions about the changes that the latest IOS doesn't act (scanning or monitoring) for our custom beacon devices. Since about 2015, We has provided some 'location based service' by using our custom iBeacon devices. However We've just realized that the latest IOS devices doesn't work with our custom iBeacon devices. but also realized It could still work with the other normal iBeacon devices. So, I've dig this issues for a while and finally I got the answer. It's because the one byte of Ibeacon advertsing packet payload. the followings are the differences about manufacturer data part between a normal Ibeacon and our custom beacon. normal Ibeacon 0xFF 0x4C00 0x02 0x15 0x736E75685F70656F706C655F74656331 0xEA61 0x03EB 0xC5 our custom Ibeacon 0xFF 0x4C00 0x02 0x15 0x736E75685F70656F706C655F74656331 0xEA61 0x03EB 0xC5 0xDA Yes, I know. after many of searches and research, Now I've understood the byte (meaning the length of following payload) should be changed as '0x16'. But It is certainly something that has worked well not so long ago. Anyway, The introduction was so long, but this is the one question what I'd like to ask about. I need to know exactly which version of IOS this change came from. (I've tried but I couldn't find any thing about this on the official documents.) I need to expaing to my customers what's going on. for that, I need the information that exactly which version of IOS It didn't work from. Thanks in advance. Regards.
1
0
428
Jan ’25
get location in app intent for interactive widgets
I have an app intent for interactive widgets. when I touch the toggle, the app intent perform to request location. func perform() async throws -> some IntentResult { var mark: LocationService.Placemark? do { mark = try await AsyncLocationServive.shared.requestLocation() print("[Widget] ConnectHandleIntent: \(mark)") } catch { WidgetHandler.shared.error = .locationUnauthorized print("[Widget] ConnectHandleIntent: \(WidgetHandler.shared.error!)") } return .result() } @available(iOSApplicationExtension 13.0, *) @available(iOS 13.0, *) final class AsyncLocationServive: NSObject, CLLocationManagerDelegate { static let shared = AsyncLocationServive() private let manager: CLLocationManager private let locationSubject: PassthroughSubject<Result<LocationService.Placemark, LocationService.Error>, Never> = .init() lazy var geocoder: CLGeocoder = { let geocoder = CLGeocoder() return geocoder }() @available(iOSApplicationExtension 14.0, *) @available(iOS 14.0, *) var isAuthorizedForWidgetUpdates: Bool { manager.isAuthorizedForWidgetUpdates } override init() { manager = CLLocationManager() super.init() manager.delegate = self } func requestLocation() async throws -> LocationService.Placemark { let result: Result<LocationService.Placemark, LocationService.Error> = try await withUnsafeThrowingContinuation { continuation in var cancellable: AnyCancellable? var didReceiveValue = false cancellable = locationSubject.sink( receiveCompletion: { _ in if !didReceiveValue { // subject completed without a value… continuation.resume(throwing: LocationService.Error.emptyLocations) } }, receiveValue: { value in // Make sure we only send a value once! guard !didReceiveValue else { return } didReceiveValue = true // Cancel current sink cancellable?.cancel() // We either got a location or an error continuation.resume(returning: value) } ) // Now that we monitor locationSubject, ask for the location DispatchQueue.global().async { self.manager.requestLocation() } } switch result { case .success(let location): // We got the location! return location case .failure(let failure): // We got an error :( throw failure } } // MARK: CLLocationManagerDelegate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { defer { manager.stopUpdatingLocation() } guard let location = locations.first else { locationSubject.send(.failure(.emptyLocations)) return } debugPrint("[Location] location: \(location.coordinate)") manager.stopUpdatingLocation() if geocoder.isGeocoding { geocoder.cancelGeocode() } geocoder.reverseGeocodeLocation(location) { [weak self] marks, error in guard let mark = marks?.last else { self?.locationSubject.send(.failure(.emptyMarks)) return } debugPrint("[Location] mark: \(mark.description)") self?.locationSubject.send(.success(mark)) } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { locationSubject.send(.failure(.errorMsg(error.localizedDescription))) } } I found it had not any response when the app intent performed. And there is a location logo tips in the top left corner of phone screen.
2
0
609
Jan ’25
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
1k
Jan ’25
Inquiry About Background Permission Issue in My App
I am writing to address a concern regarding the background permission functionality in my app, which is critical for ensuring user safety as they navigate various terrains. This feature also enables users to smoothly record their navigation tracks for review after their activities. Recently, I've noticed that this functionality is not working as seamlessly as before. Additionally, I observed that the app is not categorized under 'health and fitness'—could reclassifying it improve background activity? Before I delve into a detailed code review, I wanted to check if this issue might be related to sync or settings on the App Store side, such as permission configurations, app updates, or other related factors. Or, is it more likely an issue stemming from the app’s codebase?
1
0
453
Jan ’25
Throttling on navigator.geolocation.getCurrentPosition on Safari
I'm using navigator.geolocation.getCurrentPosition to retrieve the users coordinates in a PWA built with Nextjs. getCurrentPosition is called by clicking on a button. If getCurrentPosition is called afterwards, the cached value is returned. On Safari, If I refresh the page, or logout, login and call getCurrentPosition again, the getCurrentPosition error callback is called with an error code 2 - POSITION_UNAVAILABLE. After around five minutes, getCurrentPosition can be called again. Is there some kind of throttling restriction on Safari navigator.geolocation.getCurrentPosition?
0
0
425
Jan ’25
Tracking User Activity (Driving/Walking) Periodically with Background Execution (Background state & Terminated state)
I'm working on an application where, once the user starts driving, I need to periodically check their activity every 2.5 minutes (150 seconds) to determine whether they are still driving, walking, or have stopped. If they are still driving, I want to keep rescheduling the task until the user is no longer in a driving state. Currently, I'm using startMonitoringSignificantLocationChanges to wake the app when the user's location changes, which works as expected. However, the activity detection stops after the first result is received, and I can't continue tracking the user's activity in the background (or after the app is killed from the app switcher). Here's my approach: After receiving a significant location change, I start tracking the user’s activity to check if they are driving or have stopped. I reschedule this task every 2.5 minutes as long as the user remains in a driving state. I need this process to run even when the app is in the background or terminated by the user. Question: Is it possible to keep activity detection running periodically after receiving a location change, even when the app is in the background or terminated? What is the recommended way to implement this? I would appreciate any suggestions or best practices for achieving this functionality.
1
0
576
Jan ’25
SwiftUI creating MapCameraPosition from CLLocationManager initialiser/self error when trying to tie them? (see code)
Trying to use new Swift @Observable to monitor GPS position within SwiftUI content view. But how do I tie the latest locations to the SwiftUI Map's mapCameraPosition? Well ideally the answer could cover: How to fix this error - So get map tracking along with the User Position, but also How to include facility to turn on/off the map moving to track the user position (which I'll need to do next). So could be tracking, then disable, move map around and have a look at things, then click button to start syncing the mapcameraposition to the GPS location again Refer to error I'm embedded in the code below. import SwiftUI import MapKit @Observable final class NewLocationManager : NSObject, CLLocationManagerDelegate { var location: CLLocation? = nil private let locationManager = CLLocationManager() func startCurrentLocationUpdates() async throws { if locationManager.authorizationStatus == .notDetermined { locationManager.requestWhenInUseAuthorization() } for try await locationUpdate in CLLocationUpdate.liveUpdates() { guard let location = locationUpdate.location else { return } self.location = location } } } struct ContentView: View { var newlocationManager = NewLocationManager() @State private var cameraPosition: MapCameraPosition = .region(MKCoordinateRegion( center: newlocationManager.location?.coordinate ?? <#default value#>, span: MKCoordinateSpan(latitudeDelta: 0.25, longitudeDelta: 0.25) )) // GET ERROR: Cannot use instance member 'newlocationManager' within property initializer; property initializers run before 'self' is available var body: some View { ZStack { Map(position: $cameraPosition) Text("New location manager: \(newlocationManager.location?.description ?? "NIL" )") // works } .task { try? await newlocationManager.startCurrentLocationUpdates() } } } #Preview { ContentView() }
2
0
1.5k
Dec ’24
Can I ensure location is saved to SwiftData within Share Extension lifetime?
I am writing a SwiftData/SwiftUI app in which the user saves simple records, tagged with their current location. Core Location can take up to 10 seconds to retrieve the current location from its requestLocation() call. I the main app I have wrapped the CLLocationManager calls with async implementations. I kick off a Task when a new record is created, and write the location to my @Model on the main thread when it completes. A realistic use of the share extension doesn't give the task enough time to complete. I can use performExpiringActivity to complete background processing after the share extension closes but this needs to be a synchronous block. Is there some way of using performExpiringActivity when relying on a delegate callback from something like Core Location?
0
0
400
Dec ’24
How to search location in global rather than in local?
I'm doing a weather app, users can search locations for getting weather, but the problem is, the results only shows locations in my country, not in global. For example, I'm in China, I can't search New York, it just shows nothing. Here's my code: @Observable class SearchPlaceManager: NSObject { var searchText: String = "" let searchCompleter = MKLocalSearchCompleter() var searchResults: [MKLocalSearchCompletion] = [] override init() { super.init() searchCompleter.resultTypes = .address searchCompleter.delegate = self } @MainActor func seachLocation() { if !searchText.isEmpty { searchCompleter.queryFragment = searchText } } } extension SearchPlaceManager: MKLocalSearchCompleterDelegate { func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { withAnimation { self.searchResults = completer.results } } } Also, I've tried to set searchCompleter.region = MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 0, longitude: 0), span: MKCoordinateSpan(latitudeDelta: 180, longitudeDelta: 360) ), but it doesn't work.
2
0
760
Dec ’24
What are possible failures when using CLLocationUpdate.Updates AsyncSequence
Hello, I'm currently migrating my app location service to use the new CLLocationUpdate.Updates. I'm trying to understand what can fail in this AsyncSequence. Based on the previous CLError, I thought authorisation was one of them for example but it turns out that this is handled by the CLLocationUpdate where we can check different properties. So, is there a list of errors available somewhere? Thanks Axel, @alpennec
2
0
416
Dec ’24
didEnterRegion and didExitRegion delegate methods are called twice
When I set the values of notifyOnExit and notifyOnEnter to true when registering CLCircularRegion, I checked that the didExitRegion and didEnterRegion functions are called well. However, there is a problem that they are called twice in a row every time they are called. I was wondering if this is an internal bug in the API. There is also a stackoverflow report related to the above issue. I would appreciate your confirmation. stackoverflow - why the didEnterRegion called twice? Thank you.
1
0
515
Dec ’24