SwiftLocation icon indicating copy to clipboard operation
SwiftLocation copied to clipboard

CoreLocation returns .notDetermined before Pop Up Button is pressed

Open hactar opened this issue 1 year ago • 3 comments

I've tried using SwiftLocation in a new app I'm creating using async await. I did it according to the readme:

try await location.requestPermission(.whenInUse) // obtain the permissions
let userLocation = try await location.requestLocation() // get the location

I was however surprised that even though the app is supposed to await the requestPermission, in practice the app nearly immediately tried to request a location even though no button on the permission popup was tapped. Obviously no location was returned as no permission was granted.

Investigating the issue I found that CoreLocation immediately returns .notDetermined when the popup appears, at least it does while I was testing it on iOS 17.2. Then when the user taps a button, the correct permission is returned, but by then the await has already been continued with the wrong value: .notDetermined.

So I have added code to ignore .notDetermined - this now works for me, only once a user taps a button on the pop up, does the await return.

hactar avatar Jan 15 '24 11:01 hactar

I've tried to replicate the issue with no luck:

@IBAction public func ciao() {
        Task {
            do {
                try await location.requestPermission(.whenInUse) // obtain the permissions
                print("requested permission")
                let userLocation = try await location.requestLocation() // get the location
                print("called immediately")
            } catch {
                print(error.localizedDescription)
            }
        }
    }

In your case "called immediately" is executed right after the system popup is showed, right?

malcommac avatar Mar 05 '24 10:03 malcommac

I tried again - I think it depends on where you init Location(). If you do it within the Task the issue I describe above occurs. If I init location as part of a struct variable (on the main thread) this issue does not occur.

Maybe initing Location() within a Task isn't valid, but then there should be warnings about this I guess...

        .onAppear {
            Task {
                do {
                    let location = Location()
                    print("requesting permission")
                    try await location.requestPermission(.whenInUse) // obtain the permissions
                    print("requested permission")
                    let userLocation = try await location.requestLocation() // get the location
                    print("called immediately")
                    print("userLocation: \(userLocation)")
                } catch {
                    print(error.localizedDescription)
                }
            }
        }

hactar avatar Mar 05 '24 11:03 hactar