Disabling Location Service for map view not working
Environment
- Xcode version: 16.3
- iOS version: 18.0
- Maps SDK Version: 11.12.2
Observed behavior and steps to reproduce
When moving app to background, we want to stop location updates to save energy. on previous versions this worked:
locationProvider.removeLocationObserver(for: self) mapView.location.options.puckType = .none
Now this has no effect, the app is still requesting location updates.
Is there a workaround?
Hi @SigmaAppdevelopment, are you using our default LocationProvider or are you using your own?
We have deprecated LocationManager/locationProvider in favor of onLocationChange; if you are accessing locationProvider it will return nil, so if your provided code is after some guard expression i.e guard let locationProvider = mapView.location.locationProvider then it probably would take no effect
can you provide a bit more elaborated snippet on how you setup the map, how you're observing/unobserving location updates?
Hi here is our code
import Foundation import MapboxMaps import CoreLocation import UIKit
protocol CameraLocationConsumerDelegate: AnyObject { func onLocationUpdate(location: CLLocationCoordinate2D) }
// Create class which conforms to LocationConsumer, update the camera's centerCoordinate when a locationUpdate is received class CameraLocationConsumer: LocationObserver {
public typealias Completion = (Bool) -> ()
weak var mapView: MapView?
weak var delegate: CameraLocationConsumerDelegate? = nil
// A location provider that you use to customize location settings.
let locationProvider = AppleLocationProvider()
// initiale Location sofort setzen (keine Animation)
var animateLocationUpdates = false
var isUpdatingLocation = false
var followLocationUpdates = true
var ownerStr: String = ""
/// App hat LocationUpdates gestartet
private var locationUpdatesRequired = true
init(mapView: MapView, owner: String) {
self.ownerStr = owner
self.mapView = mapView
locationProvider.options.activityType = .fitness
locationProvider.options.desiredAccuracy = kCLLocationAccuracyBest
locationProvider.options.distanceFilter = CLLocationDistance(2)
self.mapView?.location.options.puckBearingEnabled = false // eingene Logik (rotation nur, wenn Distanz zw. Locations > 5 m)
// Override the default location provider with the custom one.
mapView.location.override(provider: locationProvider)
NotificationCenter.default.addObserver(self,
selector: #selector(appMovedToBackground),
name: UIApplication.willResignActiveNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(appMovedToForeground),
name: UIApplication.didBecomeActiveNotification,
object: nil)
}
func checkPermission(completion: @escaping Completion) {
DispatchQueue.global(qos: .userInitiated).async {
var hasPermission = false
if CLLocationManager.locationServicesEnabled() {
let manager = CLLocationManager()
switch manager.authorizationStatus {
case .notDetermined, .restricted, .denied:
hasPermission = false
case .authorizedAlways, .authorizedWhenInUse:
hasPermission = true
@unknown default:
hasPermission = false
}
}
DispatchQueue.main.async {
completion(hasPermission)
}
}
}
private func askForPermission() {
// For use in foreground
CLLocationManager().requestWhenInUseAuthorization()
}
func startLocationUpdates() {
self.locationUpdatesRequired = true
checkPermission(completion: { [weak self] hasPermission in
guard let self = self else { return }
if !hasPermission {
self.askForPermission()
} else {
if !self.isUpdatingLocation {
print("startLocationUpdates, \(self.ownerStr)")
// Register the location consumer with the map
// Note that the location manager holds weak references to consumers, which should be retained
locationProvider.addLocationObserver(for: self)
self.isUpdatingLocation = true
}
self.setPuckType()
}
})
}
/**
* @param auto: LocationUpdates werden gestoppt, wenn App in Hintergrund gelegt wird, und wieder gestartet, wenn App in Vordergrund
*/
func stopLocationUpdates(auto: Bool = false) {
if !auto {
self.locationUpdatesRequired = false
}
if isUpdatingLocation {
print("stopLocationUpdates, \(ownerStr)")
locationProvider.removeLocationObserver(for: self)
isUpdatingLocation = false
self.setPuckType()
}
}
func onLocationUpdateReceived(for locations: [Location]) {
delegate?.onLocationUpdate(location: newLocation.coordinate)
}
func setPuckType() {
if isUpdatingLocation {
if mapView?.location.options.puckType != .puck2D() {
let topImage = UIImage(named: "location-dot-inner")
let shadowImage = UIImage(named: "location-dot-outer")
let pulsing = Puck2DConfiguration.Pulsing(color: UIColor(named: "sigma_red")!, radius: .constant(30.0))
let puckConfig = Puck2DConfiguration(topImage: topImage, shadowImage: shadowImage, scale: .constant(0.8), pulsing: pulsing, showsAccuracyRing: false)
mapView?.location.options.puckType = .puck2D(puckConfig)
}
} else {
if mapView?.location.options.puckType != .none {
mapView?.location.options.puckType = .none
}
}
}
@objc func appMovedToBackground() {
stopLocationUpdates(auto: true)
}
@objc func appMovedToForeground() {
if locationUpdatesRequired {
startLocationUpdates()
}
}
}
By the way, can I disable telemetry? https://www.mapbox.com/telemetry
I only want to show static data, so there should be no location access. except one view, this has location access, so that's the reason location permission is set.
I also encountered the same problem. Can anyone tell me how to disable Mapbox positioning?