Search code examples
ioscore-locationuilocalnotification

iOS blue status bar while using geofencing/background location updates to trigger Notifications


I have in application code that enables location updates in background

locationManager.requestAlwaysAuthorization()
locationManager.delegate = self

locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters // less batery ussage
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.allowsBackgroundLocationUpdates = true

And I want to trigger Local Notifications based on user geo location.

notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { [weak self] (granted, error) in
            guard let self = self else { return }
            if granted {
                print("NotificationCenter Authorization Granted!")

                self.notificationCenter.removePendingNotificationRequests(withIdentifiers: [model.id])

                let content = UNMutableNotificationContent()
                content.title = model.name
                content.body = model.desc

                content.categoryIdentifier = "Location Notification"
                content.userInfo["model_id"] = model.id
                content.sound = UNNotificationSound.default

                let region = self.makeRegion(for: model)

                let trigger = UNLocationNotificationTrigger(region: region, repeats: true)
                let request = UNNotificationRequest(identifier: restaurant.id, content: content, trigger: trigger)

                self.notificationCenter.add(request)
            }
        }

locationManager.startUpdatingLocation()

Now I have blue status bar indicator about Location updates all the time while app is in foreground or in background. I think it is to obstrusive to the end user to be appeared all the time.

I heard that this will be displayed while user grant While in Use authorization status for Core Location. So as I understand I should only enable triggering this notification while application is in foreground (but what changes are needed here? allowsBackgroundLocationUpdates = false ?)

And only use background user location updates when user has granted Always Authorization status.

But odd thing is that this blue bard indicator also appears while application is in foreground.

UPDATE

Ok I have Ask Next Time set then Blue indicator is always displayed.

If there is While in Use then Blue indicator is only in background.

It here is Alway there is no blue indicator at all.

I consider to add such delegate method

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {

        print("Core Location authorization status: \(status)")

        switch status {
        case .authorizedAlways:
            locationManager.allowsBackgroundLocationUpdates = true
        default:
            locationManager.allowsBackgroundLocationUpdates = false
        }
    }

I think it should solve blue indicator obtrusive display in status bar. And the only problem will be that If user in iOS 13 selects While In Use then there will not be attempt to update location in background, so at the end there won't be occasion to display alert with question about Always Authorization, and the only possibility will be to user manually turn Always in Settings?

So my question here is how to make in iOS 13 it in that way the Alert with question about Always Authorization appear and only then change

.allowsBackgroundLocationUpdates = true

to

.allowsBackgroundLocationUpdates = false

Solution

  • The problem is that everything you're doing is wrong.

    You are not doing background location monitoring so you should not be asking for Always authorization. You don't need it, and in the end you won't get it. You should ask for WhenInUse authorization and that's all. (That's sufficient for a notification geofence trigger.)

    As for the blue bar, the rule is the same as it is always been: you should set

    locationManager.allowsBackgroundLocationUpdates = true
    

    only when you are about to go into the background while you are already updating locations, and you should set

    locationManager.allowsBackgroundLocationUpdates = false
    

    when you return to the foreground. If you are not actually running in the background (with a Background capability) while updating locations, do not use allowsBackgroundLocationUpdates at all.

    Just do what you're supposed to do, and all will be well.