Search code examples
iosswiftswiftuiphphotolibrary

How do I show/hide a view with SwiftUI based on PHPhotoLibraryAuthorizationStatus?


I'm trying to get a view to show in SwiftUI if the user has not given permission for access to the PhotoLibrary (Giving them instructions to allow access to the Photo Library, either with a prompt or to go into Settings and fix the status). Now I'm assuming that PHPhotoLibrary.authorizationStatus is my source of truth, but maybe I haven't fully understood the concept

 var canAccessPhotos : Bool {
        return PHPhotoLibrary.authorizationStatus() == .authorized
 }

...

.sheet(isPresented: canAccessPhotos) { //Error: Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'
     AccessPhotoLibraryView() //New View I want to show the user with instructions or prompt
}

Now that doesn't work because canAccessPhotos is not bindable, but I also can't put a @Binding on a computed property and there's currently no mechanism for the variable to update when authorizationStatus changes, so I'm stuck on the next bit on how to solve it.

How do I get the property from PHPhotoLibrary to automatically show the view if/when it changes. Or is there a different way to do it and I've gone in the wrong direction?

Thank you in advanced 🙂


Solution

  • Ok, you'd better use a coordinator (or a view model) for this problem. Have a look at the code below and let me know if it works for you.

    class Coordinator: NSObject, ObservableObject, PHPhotoLibraryChangeObserver {
    
        @Published var isPhotoLibraryAuthorized = false
    
        override init() {
            super.init()
            PHPhotoLibrary.shared().register(self)
            updateStatus()
        }
    
        func photoLibraryDidChange(_ changeInstance: PHChange) {
            updateStatus()
        }
    
        private func updateStatus() {
            DispatchQueue.main.async {
                self.isPhotoLibraryAuthorized = PHPhotoLibrary.authorizationStatus() == .authorized
            }
        }
    }
    
    struct ContentView: View {
    
        @EnvironmentObject var coordinator: Coordinator
    
        var body: some View {
            Group {
                if coordinator.isPhotoLibraryAuthorized {
                    // some view
                } else {
                    // another view
                }
            }
        }
    }