Skip to content

Instantly share code, notes, and snippets.

@shishirthedev
Last active December 4, 2023 20:13
Show Gist options
  • Save shishirthedev/88359369f8f99603de95051ece4bfbfe to your computer and use it in GitHub Desktop.
Save shishirthedev/88359369f8f99603de95051ece4bfbfe to your computer and use it in GitHub Desktop.
import UIKit
import Photos
import Contacts
import AVFoundation
enum Permission {
case cameraUsage
case contactUsage
case photoLibraryUsage
case microphoneUsage
}
class PermissionManager {
private init(){}
public static let shared = PermissionManager()
let PHOTO_LIBRARY_PERMISSION: String = "Require access to Photo library to proceed. Would you like to open settings and grant permission to photo library?"
let CAMERA_USAGE_PERMISSION: String = "Require access to Camera to proceed. Would you like to open settings and grant permission to camera ?"
let CONTACT_USAGE_ALERT: String = "Require access to Contact to proceed. Would you like to open Settings and grant permission to Contact?"
let MICROPHONE_USAGE_ALERT: String = "Require access to microphone to proceed. Would you like to open Settings and grant permissiont to Microphone?"
func requestAccess(vc: UIViewController,
_ permission: Permission,
completionHandler: @escaping (_ accessGranted: Bool) -> Void){
switch permission {
case .cameraUsage: ////////////////// Camera
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
completionHandler(true)
case .denied:
showSettingsAlert(controller: vc, msg: CAMERA_USAGE_PERMISSION, completionHandler)
case .restricted, .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { granted in
if granted {
completionHandler(true)
} else {
DispatchQueue.main.async {
self.showSettingsAlert(controller: vc, msg: self.CAMERA_USAGE_PERMISSION, completionHandler)
}
}
}
}
break
case .contactUsage: ///////////////////// Contact
switch CNContactStore.authorizationStatus(for: .contacts) {
case .authorized:
completionHandler(true)
case .denied:
showSettingsAlert(controller: vc, msg: CONTACT_USAGE_ALERT, completionHandler)
case .restricted, .notDetermined:
CNContactStore.init().requestAccess(for: .contacts) { granted, error in
if granted {
completionHandler(true)
} else {
DispatchQueue.main.async {
self.showSettingsAlert(controller: vc, msg: self.CONTACT_USAGE_ALERT, completionHandler)
}
}
}
}
break
case .photoLibraryUsage: ///////////////////// Photo library
switch PHPhotoLibrary.authorizationStatus() {
case .authorized:
completionHandler(true)
case .denied:
showSettingsAlert(controller: vc, msg: PHOTO_LIBRARY_PERMISSION, completionHandler)
case .restricted, .notDetermined:
PHPhotoLibrary.requestAuthorization { (status) in
if status == .authorized{
completionHandler(true)
}else{
DispatchQueue.main.async {
self.showSettingsAlert(controller: vc, msg: self.PHOTO_LIBRARY_PERMISSION, completionHandler)
}
}
}
}
break
case .microphoneUsage: //////////////////////// Microphone usage
switch AVAudioSession.sharedInstance().recordPermission(){
case .granted:
completionHandler(true)
break
case .denied:
showSettingsAlert(controller: vc, msg: MICROPHONE_USAGE_ALERT, completionHandler)
break
case .undetermined:
AVAudioSession.sharedInstance().requestRecordPermission({ (granted) in
if granted{
completionHandler(true)
}else{
DispatchQueue.main.async {
self.showSettingsAlert(controller: vc, msg: self.MICROPHONE_USAGE_ALERT, completionHandler)
}
}
})
break
}
}
}
private func showSettingsAlert(controller: UIViewController ,
msg: String,
_ completionHandler: @escaping (_ accessGranted: Bool) -> Void) {
let alert = UIAlertController(title: nil, message: msg, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { action in
completionHandler(false)
if let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) {
if UIApplication.shared.canOpenURL(settingsUrl){
if #available(iOS 10.0, *) {
UIApplication.shared.open(settingsUrl)
} else {
UIApplication.shared.openURL(settingsUrl)
}
}
}
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { action in
completionHandler(false)
})
controller.present(alert, animated: true)
}
}
/////////////////////////////////////////////////////////////////////////
/////// Don't forget to add permission in info.plist from privacy ///////
/////////////////////////////////////////////////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment