How to check if user revoked HealthKit permissions through Settings and act in response to it?

Viewed 20

I am using Apple's HealthKit to build an app, and am requesting permission from the user to read and write Sleep Data as soon as a View loads using SwiftUI's .onAppear modifier.

It all works fine and I get the data I need using this method. However, if a user revokes the read and write permissions for my app through Settings, instead of requesting permission again, the app crashes. This is how I have set things up.

    @State var authorized: Bool = false

    var body: some View {
       
            Text("\(initTextContent)")
                .onAppear {
                    healthstore.getHealthAuthorization(completionAuth:  {success in
                        authorized = success

                        if self.authorized == true {
                            healthstore.getSleepMetrics(startDate: sevendaysAgo, endDate: sevendaysAfter, completion: sleepDictAssign)
                        }
                        
                        else {
                            initTextContent = "Required Authorization Not Provided"
                        }
                    })
                }
}

I've created a class called healthstore and am simply using HealthKit's requestAuthorization method as follows:

var healthStore: HKHealthStore()
func getHealthAuthorization(completionAuth: @escaping (Bool) -> Void) { 
//we will call this inside our view

        healthStore.requestAuthorization(toShare: [sleepSampleType], read: [sleepSampleType]) { (success, error) in
            if let error = error {
                // Handle the error here.
                fatalError("*** An error occurred \(error.localizedDescription) ***")
            }
            else {
                completion(success)
            }
        }
}

1 Answers

If the user revoked the permisions they are revoked. You cannot ask again. If you want to handle this scenario you would need to throw the error and handle it outside of the function by showing a message to the user asking them to enable it again.

Or simply return the success boolean ignoring the error.

func getHealthAuthorization(completionAuth: @escaping (Bool) -> Void) { 
//we will call this inside our view

        healthStore.requestAuthorization(toShare: [sleepSampleType], read: [sleepSampleType]) { (success, error) in
            //ignore error since your func can just return a boolean
            completion(success)
        }
}
Related