You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

217 lines
7.1 KiB

//
// 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?
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) {
func openPicker() {
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.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
}
PermissionHelper.isAllowedToRecordVideo { (isAllowed) in
if isAllowed {
openPicker()
} else {
self.presenter?.presenting().alert(message: "camera_access_denied_text", okAction: {
UIApplication.tryURL(url: UIApplication.openSettingsURLString)
})
}
}
}
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
}
}