Created
November 28, 2022 15:16
-
-
Save ashishkanani/86127cf302063b0442eef9b6e237f926 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
// | |
// MediaPicker.swift | |
// | |
/* | |
The last step you must open info.plist in your Xcode project. By write dictinary value as follow | |
key → Privacy - Camera Usage Description, value → $(PRODUCT_NAME) Camera use. | |
key → Privacy - Photo Library Usage Description, value → $(PRODUCT_NAME) Photo use. | |
*/ | |
import Foundation | |
import UIKit | |
import MobileCoreServices | |
import AVKit | |
enum MediaType { | |
case image | |
case video | |
case media | |
case file | |
} | |
struct Constants { | |
static let photoCamera = "Photo Camera" | |
static let videoCamera = "Video Camera" | |
static let photoGallery = "Photo Gallery" | |
static let videoGallery = "Video Gallery" | |
static let file = "File" | |
static let cancel = "Cancel" | |
static let documentTypes = ["com.microsoft.word.doc", "public.data", "org.openxmlformats.wordprocessingml.document", kUTTypePDF as String] //Use for specify type you need to pickup | |
} | |
class MediaPicker: NSObject { //Inherit NSObject | |
static let shared: MediaPicker = MediaPicker() //Singleton Pattern | |
fileprivate var currentViewController: UIViewController! | |
var imagePickerBlock: ((_ image: UIImage, _ url: URL?) -> Void)? | |
var videoPickerBlock: ((_ data: Data?, _ thumbNail: UIImage) -> Void)? | |
var filePickerBlock: ((_ url: URL) -> Void)? | |
} | |
extension MediaPicker { | |
func showActionSheet(viewController: UIViewController, type: MediaType) { | |
currentViewController = viewController | |
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) | |
let photoCamera = UIAlertAction(title: Constants.photoCamera, style: .default, handler: { (action) -> Void in | |
self.photoCamera() | |
}) | |
let videoCamera = UIAlertAction(title: Constants.videoCamera, style: .default, handler: { (action) -> Void in | |
self.videoCamera() | |
}) | |
let photoGallery = UIAlertAction(title: Constants.photoGallery, style: .default, handler: { (action) -> Void in | |
self.photoGallary() | |
}) | |
let videoGallery = UIAlertAction(title: Constants.videoGallery, style: .default, handler: { (action) -> Void in | |
self.videoGallary() | |
}) | |
let file = UIAlertAction(title: Constants.file, style: .default, handler: { (action) -> Void in | |
self.file() | |
}) | |
let cancel = UIAlertAction(title: Constants.cancel, style: .cancel, handler: nil) | |
if type == .image { | |
actionSheet.addAction(photoCamera) | |
actionSheet.addAction(photoGallery) | |
} else if type == .video { | |
actionSheet.addAction(videoCamera) | |
actionSheet.addAction(videoGallery) | |
} else if type == .media { | |
actionSheet.addAction(photoCamera) | |
actionSheet.addAction(photoGallery) | |
actionSheet.addAction(videoCamera) | |
actionSheet.addAction(videoGallery) | |
} else if type == .file { | |
actionSheet.addAction(file) | |
} | |
actionSheet.addAction(cancel) | |
viewController.present(actionSheet, animated: true, completion: nil) | |
} | |
} | |
extension MediaPicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate { | |
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { | |
// currentViewController.dismiss(animated: true, completion: nil) | |
picker.dismiss(animated: true) | |
} | |
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { | |
picker.dismiss(animated: true, completion: nil) | |
if let image = info[.editedImage] as? UIImage { | |
let imageURL = info[.imageURL] as? URL | |
imagePickerBlock?(image, imageURL) //return image when not null | |
} else if let image = info[.originalImage] as? UIImage { | |
let imageURL = info[.imageURL] as? URL | |
imagePickerBlock?(image, imageURL) //return image when not null | |
} else if let image = info[.imageURL] as? UIImage { | |
imagePickerBlock?(image, nil) //return image when not null | |
} else if let videoUrl = info[.mediaURL] as? URL { | |
let thumbNail = generateThumbnail(path: videoUrl) ?? UIImage(named: "img_woooba_ball")! | |
let data = try? Data(contentsOf: videoUrl) | |
videoPickerBlock?(data, thumbNail) //return video url when not null | |
} | |
// currentViewController.dismiss(animated: true, completion: nil) | |
} | |
} | |
extension MediaPicker: UIDocumentMenuDelegate, UIDocumentPickerDelegate { | |
func documentMenu(_ documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) { | |
documentPicker.delegate = self | |
currentViewController.present(documentPicker, animated: true, completion: nil) | |
} | |
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { | |
controller.delegate = self | |
currentViewController.present(controller, animated: true, completion: nil) | |
} | |
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) { | |
filePickerBlock?(url) //return file url if you selected from drive. | |
} | |
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { | |
controller.dismiss(animated: true, completion: nil) | |
} | |
} | |
extension MediaPicker { | |
fileprivate func photoCamera() { | |
if UIImagePickerController.isSourceTypeAvailable(.camera) { | |
let pickerController = UIImagePickerController() | |
pickerController.allowsEditing = false | |
pickerController.delegate = self; | |
pickerController.sourceType = .camera | |
currentViewController.present(pickerController, animated: true, completion: nil) | |
} | |
} | |
fileprivate func videoCamera() { | |
if UIImagePickerController.isSourceTypeAvailable(.camera) { | |
let pickerController = UIImagePickerController() | |
pickerController.delegate = self | |
pickerController.allowsEditing = false | |
pickerController.sourceType = .camera | |
pickerController.mediaTypes = [kUTTypeMovie as String, kUTTypeVideo as String] | |
pickerController.videoMaximumDuration = 10 | |
currentViewController.present(pickerController, animated: true, completion: nil) | |
} | |
} | |
fileprivate func photoGallary() { | |
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { | |
let pickerController = UIImagePickerController() | |
pickerController.delegate = self; | |
pickerController.allowsEditing = false | |
pickerController.sourceType = .photoLibrary | |
currentViewController.present(pickerController, animated: true, completion: nil) | |
} | |
} | |
fileprivate func videoGallary() { | |
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) { | |
let pickerController = UIImagePickerController() | |
pickerController.delegate = self | |
pickerController.allowsEditing = true | |
pickerController.sourceType = .photoLibrary | |
pickerController.mediaTypes = [kUTTypeMovie as String, kUTTypeVideo as String] | |
pickerController.videoMaximumDuration = 10 | |
currentViewController.present(pickerController, animated: true, completion: nil) | |
} | |
} | |
fileprivate func file() { | |
let importMenuViewController = UIDocumentPickerViewController(documentTypes: Constants.documentTypes, in: .import) | |
importMenuViewController.delegate = self | |
importMenuViewController.modalPresentationStyle = .formSheet | |
currentViewController.present(importMenuViewController, animated: true, completion: nil) | |
} | |
} | |
/* | |
// How to usage. | |
class MockupViewController: UIViewController { | |
private var image: UIImage? | |
private var video: Data? | |
private var file: URL? | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
MediaPicker.shared.showActionSheet(viewController: self, type: .all) | |
//Receive Image | |
MediaPicker.shared.imagePickerBlock = { (image, _) -> Void in | |
self.image = image | |
} | |
//Receive Video | |
MediaPicker.shared.videoPickerBlock = { (video) -> Void in | |
self.video = video | |
} | |
//Receive File | |
MediaPicker.shared.filePickerBlock = { (file) -> Void in | |
self.file = file | |
} | |
} | |
} | |
*/ | |
extension MediaPicker { | |
func generateThumbnail(path: URL) -> UIImage? { | |
do { | |
let asset = AVURLAsset(url: path, options: nil) | |
let imgGenerator = AVAssetImageGenerator(asset: asset) | |
imgGenerator.appliesPreferredTrackTransform = true | |
let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil) | |
let thumbnail = UIImage(cgImage: cgImage) | |
return thumbnail | |
} catch let error { | |
print("*** Error generating thumbnail: \(error.localizedDescription)") | |
return nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment