Created
February 6, 2019 05:27
-
-
Save shishirthedev/ff488ea646209c21e7fdbf13f856b179 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ViewController: UIViewController { | |
@IBOutlet weak var imageView: UIImageView! | |
var imagePicker: UIImagePickerController! | |
enum ImageSource { | |
case photoLibrary | |
case camera | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
} | |
@IBAction func onBtnClicked(_ sender: UIButton){ | |
if sender.tag == 0 { // Photo Gallery... | |
PermissionManager.shared.requestAccess(vc: self, .photoLibraryUsage) { (isGranted) in | |
if isGranted{ | |
self.selectImageFrom(.photoLibrary) | |
} | |
} | |
}else if sender.tag == 1 { // CAMERA... | |
if UIImagePickerController.isSourceTypeAvailable(.camera){ | |
PermissionManager.shared.requestAccess(vc: self, .cameraUsage) { (isGranted) in | |
self.selectImageFrom(.camera) | |
} | |
}else{ | |
let alert = UIAlertController(title: "Error", message: "You have no camera to capture image.", preferredStyle: .alert) | |
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) | |
self.present(alert, animated: true, completion: nil) | |
} | |
}else if (sender.tag == 3){ // Save Image to Photo Library | |
guard let image = imageView.image else { return} | |
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil) | |
} | |
} | |
func selectImageFrom(_ source: ImageSource){ | |
imagePicker = UIImagePickerController() | |
imagePicker.delegate = self | |
imagePicker.allowsEditing = false | |
switch source { | |
case .camera: | |
imagePicker.sourceType = .camera | |
imagePicker.cameraCaptureMode = .photo | |
case .photoLibrary: | |
imagePicker.sourceType = .photoLibrary | |
} | |
present(imagePicker, animated: true, completion: nil) | |
} | |
} | |
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{ | |
@objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) { | |
if let error = error { | |
let ac = UIAlertController(title: "Save error", message: error.localizedDescription, preferredStyle: .alert) | |
ac.addAction(UIAlertAction(title: "OK", style: .default)) | |
present(ac, animated: true) | |
} else { | |
let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .alert) | |
ac.addAction(UIAlertAction(title: "OK", style: .default)) | |
present(ac, animated: true) | |
} | |
} | |
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { | |
picker.dismiss(animated: true, completion: nil) | |
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else { | |
print("Image not found!") | |
return | |
} | |
imageView.image = selectedImage | |
} | |
} | |
////////////////////////////////////////////// Permission Manager //////////////////////////////////// | |
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