// // MultiMediaManager.swift // // // Created by shishir sapkota // import UIKit import Foundation import AVFoundation import Photos //import RSKImageCropper @objc protocol MultiMediaManagerDelegate { @objc optional func cropSize() -> CGSize @objc optional func didFinishPickingWithImage(image: UIImage) func didFinishPickingWithError(error: String) @objc optional func didFinishPickingVideo(url: URL) } @objc protocol MultimediaPresenterProtocol { func presenting() -> UIViewController } class MultiMediaManager: NSObject { private let imagePicker = UIImagePickerController() private weak var presenter: MultimediaPresenterProtocol? weak var delegate: MultiMediaManagerDelegate? var counter = 0 init(presenter: MultimediaPresenterProtocol) { self.presenter = presenter super.init() imagePicker.delegate = self imagePicker.allowsEditing = true } func openCameraPicker() { self.openCamera(mode: .photo) } func openPicker(mode: UIImagePickerController.CameraCaptureMode) { var presentationStyle: UIAlertController.Style = .actionSheet if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad) { presentationStyle = .alert } let alertController = UIAlertController( title: nil, message: "JME would like to access your camera", preferredStyle: presentationStyle ) let cameraAction = UIAlertAction( title: "camera_text".localized(), style: UIAlertAction.Style.default ) { (_) in self.openCamera(mode: .photo) } let galleryAction = UIAlertAction( title: "gallery_text".localized(), style: UIAlertAction.Style.default ) { (_) in self.showPhotoGallery(mode: mode) } let cancelAction = UIAlertAction(title: "cancel_text".localized(), style: .cancel, handler: nil) alertController.addAction(cameraAction) // if DevicePlatform.isSimulator { alertController.addAction(galleryAction) // } alertController.addAction(cancelAction) alertController.modalPresentationStyle = .overFullScreen self.presentViewController(viewController: alertController, animated: true, completion: nil) } private func presentViewController( viewController: UIViewController, animated: Bool, completion: (() -> Void)? ) { OperationQueue.main.addOperation { self.presenter?.presenting().present(viewController, animated: animated, completion: completion) } } func openCamera(mode: UIImagePickerController.CameraCaptureMode) { PermissionHelper.isAllowedToRecordVideo { (isAllowed) in if isAllowed { self.openPicker(mode) } else { self.presenter?.presenting().alert(message: "camera_access_denied_text", okAction: { UIApplication.tryURL(url: UIApplication.openSettingsURLString) }) } } } func openPicker(_ mode: UIImagePickerController.CameraCaptureMode) { self.imagePicker.sourceType = UIImagePickerController.SourceType.camera let mediaTypes = ["public.image"] self.imagePicker.mediaTypes = mediaTypes self.imagePicker.cameraCaptureMode = mode self.imagePicker.allowsEditing = false self.imagePicker.modalPresentationStyle = .overFullScreen self.imagePicker.delegate = self counter += 1 // let overlay = createOverlay(view: imagePicker.cameraOverlayView!) // imagePicker.view.addSubview(overlay) // if !self.imagePicker.isBeingPresented { // DispatchQueue.main.async { // self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil) // } // } if counter == 1 { self.presentViewController(viewController: self.imagePicker, animated: true) { self.counter = 0 } // self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil) } // } print("123123123123 \(counter)") } func createOverlay(view: UIView) -> UIView { let overlayView = UIView() overlayView.frame = CGRect(x: 100, y: 100, width: view.frame.width, height: view.frame.height - 200) overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.7) let path = CGMutablePath() let w = UIScreen.main.bounds.width let h = UIScreen.main.bounds.height path.addRoundedRect(in: CGRect(x: 30, y: 200, width: overlayView.frame.width-60, height: overlayView.frame.width - 150), cornerWidth: 5, cornerHeight: 5) path.closeSubpath() let shape = CAShapeLayer() shape.path = path shape.lineWidth = 5.0 shape.strokeColor = UIColor.white.cgColor shape.fillColor = UIColor.white.cgColor overlayView.layer.addSublayer(shape) path.addRect(CGRect(origin: .zero, size: overlayView.frame.size)) let maskLayer = CAShapeLayer() maskLayer.backgroundColor = UIColor.black.cgColor maskLayer.path = path maskLayer.fillRule = CAShapeLayerFillRule.evenOdd overlayView.layer.mask = maskLayer overlayView.clipsToBounds = true return overlayView } private func showPhotoGallery(mode: UIImagePickerController.CameraCaptureMode) { PermissionHelper.isAllowedToShowGallary { (isAllowed) in DispatchQueue.main.async { if isAllowed { self.imagePicker.allowsEditing = false self.imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary let mediaTypes = mode == .video ? ["public.image", "public.movie"] : ["public.image"] self.imagePicker.mediaTypes = mediaTypes self.imagePicker.modalPresentationStyle = .overFullScreen self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil) } else { self.presenter?.presenting().alert( message: "galery_access_denied_text".localized(), okAction: { UIApplication.tryURL(url: UIApplication.openSettingsURLString) } ) } } } } func resizeImage(image: UIImage, to targetSize: CGSize) -> UIImage? { // This is the rect that we've calculated out and this is what is actually used below let rect = CGRect(origin: CGPoint.zero, size: targetSize) // Actually do the resizing to the rect using the ImageContext stuff UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0) image.draw(in: rect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } } extension MultiMediaManager: UIImagePickerControllerDelegate { func imagePickerController( _ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any] ) { let info = Dictionary(uniqueKeysWithValues: info.map {key, value in (key.rawValue, value)}) var completion: (() -> Void)? if let mediaType = info["UIImagePickerControllerMediaType"] as? String { if mediaType == "public.image" { if let picture = info[ UIImagePickerController.InfoKey.originalImage.rawValue ] as? UIImage { if let cropsize = self.delegate?.cropSize?() { if picture.size.width < cropsize.width || picture.size.height < cropsize.height { let message = "Image size must be greater than \(cropsize.width) X \(cropsize.height)" self.delegate?.didFinishPickingWithError(error: message) } else { guard let resizedImage = self.resizeImage(image: picture, to: cropsize) else { return } completion = { self.delegate?.didFinishPickingWithImage?(image: resizedImage) } } } else { completion = { self.delegate?.didFinishPickingWithImage?(image: picture) } } } } else if mediaType == "public.movie" { // _ = info["UIImagePickerControllerMediaURL"] as! URL return } } picker.dismiss(animated: true) { completion?() } } } extension MultiMediaManager: UINavigationControllerDelegate { } struct PermissionHelper { static func isAllowedToRecordVideo(completion: @escaping (Bool) -> Void) { let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video) completion(status != .denied && status != .restricted) } static func isAllowedToRecordSound(completion: @escaping (Bool) -> Void) { AVAudioSession.sharedInstance().requestRecordPermission(completion) } static func isAllowedToShowGallary(completion: @escaping (Bool) -> Void) { PHPhotoLibrary.requestAuthorization { (status) in completion(status == .authorized) } } } struct DevicePlatform { static var isSimulator: Bool { #if targetEnvironment(simulator) // We're on the simulator return true #else // We're on a device return false #endif } }