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.
277 lines
9.2 KiB
277 lines
9.2 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?
|
|
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
|
|
}
|
|
}
|