Yuuu
Yuuu

Reputation: 879

Refactor code for two switch case statement

I'm working on a swift project and have a question to refactor my code.

I'm writing code for checking if a user authorized both the camera and microphone authorization in the app. I wrote the following codes, but I guess (and I hope) I can refactor the code because I think the code below is unclear. I understood basic Swift grammar and gradually understood the compiled language, but let me know if there is a way to make this more readable or easy to write.

What I want to do here is...

What I did was, first check the camera authorization in checkAuthStatus and then, if the camera is authorized, trigger checkMicrophoneStatus() to check the mic authorization. The reason why I think this code is unclear is, I only write a function to check the camera authorization in checkAuthStatus() funciton. I think if it is clear if I can write something like

func checkAuthStatus(){
    // check both cameara and microphone is authorized.
    // if both of them are authorized, show next VC with showNextVC() function.
}

Upvotes: 1

Views: 199

Answers (3)

Sweeper
Sweeper

Reputation: 272905

One way is to add an onAuthorised closure parameter to both functions. The two checkXXXStatus functions also has quite a lot in common. We don't need to duplicate the switch statement.

func checkMediaStatus(type: AVMediaType, deviceName: String, onAuthorised: (() -> Void)?) {
    switch AVCaptureDevice.authorizationStatus(for: type){
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: type) { granted in
            if granted {
                print("Now it's granted")
            }
        }
    case .restricted:
        print("restricted")
        showConfigurationAlert(for: deviceName)
    case .denied:
        print("denied")
        showConfigurationAlert(for: deviceName)
    case .authorized:
        print(("authorized"))
        onAuthorised?()
    @unknown default:
        print("unknown")
    }
}

func checkMicrophoneStatus(onAuthorised: (() -> Void)?) {
    checkMediaStatus(type: .audio, deviceName: "microphone", onAuthorised: onAuthorised)
}

func checkCameraStatus(onAuthorised: (() -> Void)?) {
    checkMediaStatus(type: .video, deviceName: "camera", onAuthorised: onAuthorised)
}

Then checkAuthStatus can be written as:

func checkAuthStatus(){
    checkCameraStatus {
        self.checkMicrophoneStatus {
            self.showNextVC()
        }
    }
}

Also note that you might also want to call onAuthorised and showConfigurationAlert in the requestAccess completion handler. I think this is a better design.

if granted {
    print("Now it's granted")
    onAuthorised?()
} else {
    showConfigurationAlert(for: deviceName)
}

Upvotes: 1

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119774

I think you are looking for something like this:

let videoStatus = AVCaptureDevice.authorizationStatus(for: .video)
let audioStatus = AVCaptureDevice.authorizationStatus(for: .audio)

switch (videoStatus, audioStatus) {
case (.authorized, .authorized): showNextVC()
case (.authorized, _): showConfigurationAlert(for: "microphone")
case (_, .authorized): showConfigurationAlert(for: "camera")
default: print(videoStatus, audioStatus)
}

You can check both cases at the same time and handle each of them you like

Upvotes: 1

David Miller
David Miller

Reputation: 61

You could change checkCameraStatus() and checkMicrophoneStatus() to return a bool and inside checkAuthStatus() change to :

func checkAuthStatus(){
    let cameraAuthorised = checkCameraStatus()
    let micAuthorised = checkMicrophoneStatus()

    if (cameraAuthorised && micAuthorised) {
        showNextVC()
    }
 }

Upvotes: 1

Related Questions