Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - How to handle camera permissions?

Tags:

ios

swift

swiftui

My ImagePicker works as expected. However, I'm trying to implement camera permission handling and I seem to have gotten stuck. I am receiving the error: "Missing return in function expected return UIImagePickerController" and rightfully so. I am not sure where else I can put the switch statement to carry out the handling. Any help is appreciated.

struct ImagePicker: UIViewControllerRepresentable {
    
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    @Binding var selectedImage: UIImage
    @Binding var alertCameraAccessNeeded: Bool
    @Environment(\.presentationMode) private var presentationMode
    @EnvironmentObject private var userManager: UserManager
    
    let cameraAuthStatus = AVCaptureDevice.authorizationStatus(for: .video)
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        
        switch cameraAuthStatus {
        case .notDetermined: requestCameraPermission()
        case .authorized:
            
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = context.coordinator
            imagePicker.allowsEditing = true
            imagePicker.sourceType = sourceType
            
            return imagePicker
            
        case .restricted, .denied: self.alertCameraAccessNeeded = true
            
        @unknown default:
            fatalError()
        }
        
        
    }
    
    func requestCameraPermission() {
        AVCaptureDevice.requestAccess(for: .video, completionHandler: {accessGranted in
            guard accessGranted == true else { return }
            
        })
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self, userManager: userManager)
    }
    
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
        
    }
    
    
    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        
        let parent: ImagePicker
        let userManager: UserManager
        
        
        init(_ parent: ImagePicker, userManager: UserManager) {
            self.parent = parent
            self.userManager = userManager
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[.editedImage] as? UIImage {
                parent.selectedImage = image
                userManager.uploadProfilePicture(image: image)
            }
            
            
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}
like image 938
devOP1 Avatar asked Oct 26 '25 17:10

devOP1


1 Answers

In response to your comments, wanting to know how to request permission and only conditionally display the image picker, here's a simple example that allows you to either imperatively take an action (for example, setting a @State variable) or conditionally display a view if you have permission.

Permission is requested in onAppear, but could also get moved to a button press or something like that.

class CameraManager : ObservableObject {
    @Published var permissionGranted = false
    
    func requestPermission() {
        AVCaptureDevice.requestAccess(for: .video, completionHandler: {accessGranted in
            DispatchQueue.main.async {
                self.permissionGranted = accessGranted
            }
        })
    }
}

struct ContentView: View {
    @StateObject var cameraManager = CameraManager()
    
    var body: some View {
        VStack {
            Text("Hello, world")
            if cameraManager.permissionGranted {
                //show a conditional view only if you have permission
            }
        }
        .onReceive(cameraManager.$permissionGranted, perform: { (granted) in
            if granted {
                //show image picker controller
            }
        })
        .onAppear {
            cameraManager.requestPermission()
        }
    }
}
like image 54
jnpdx Avatar answered Oct 28 '25 07:10

jnpdx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!