Skip to content

Instantly share code, notes, and snippets.

@shishirthedev
Created February 6, 2019 05:27
Show Gist options
  • Save shishirthedev/ff488ea646209c21e7fdbf13f856b179 to your computer and use it in GitHub Desktop.
Save shishirthedev/ff488ea646209c21e7fdbf13f856b179 to your computer and use it in GitHub Desktop.
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