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

6 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
5 years ago
  1. //
  2. // MultiMediaManager.swift
  3. //
  4. //
  5. // Created by shishir sapkota
  6. //
  7. import UIKit
  8. import Foundation
  9. import AVFoundation
  10. import Photos
  11. //import RSKImageCropper
  12. @objc protocol MultiMediaManagerDelegate {
  13. @objc optional func cropSize() -> CGSize
  14. @objc optional func didFinishPickingWithImage(image: UIImage)
  15. func didFinishPickingWithError(error: String)
  16. @objc optional func didFinishPickingVideo(url: URL)
  17. }
  18. @objc protocol MultimediaPresenterProtocol {
  19. func presenting() -> UIViewController
  20. }
  21. class MultiMediaManager: NSObject {
  22. private let imagePicker = UIImagePickerController()
  23. private weak var presenter: MultimediaPresenterProtocol?
  24. weak var delegate: MultiMediaManagerDelegate?
  25. var counter = 0
  26. init(presenter: MultimediaPresenterProtocol) {
  27. self.presenter = presenter
  28. super.init()
  29. imagePicker.delegate = self
  30. imagePicker.allowsEditing = true
  31. }
  32. func openCameraPicker() {
  33. self.openCamera(mode: .photo)
  34. }
  35. func openPicker(mode: UIImagePickerController.CameraCaptureMode) {
  36. var presentationStyle: UIAlertController.Style = .actionSheet
  37. if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad) {
  38. presentationStyle = .alert
  39. }
  40. let alertController = UIAlertController(
  41. title: nil,
  42. message: "JME would like to access your camera",
  43. preferredStyle: presentationStyle
  44. )
  45. let cameraAction = UIAlertAction(
  46. title: "camera_text".localized(),
  47. style: UIAlertAction.Style.default
  48. ) { (_) in
  49. self.openCamera(mode: .photo)
  50. }
  51. let galleryAction = UIAlertAction(
  52. title: "gallery_text".localized(),
  53. style: UIAlertAction.Style.default
  54. ) { (_) in
  55. self.showPhotoGallery(mode: mode)
  56. }
  57. let cancelAction = UIAlertAction(title: "cancel_text".localized(), style: .cancel, handler: nil)
  58. alertController.addAction(cameraAction)
  59. // if DevicePlatform.isSimulator {
  60. alertController.addAction(galleryAction)
  61. // }
  62. alertController.addAction(cancelAction)
  63. alertController.modalPresentationStyle = .overFullScreen
  64. self.presentViewController(viewController: alertController, animated: true, completion: nil)
  65. }
  66. private func presentViewController(
  67. viewController: UIViewController,
  68. animated: Bool,
  69. completion: (() -> Void)?
  70. ) {
  71. OperationQueue.main.addOperation {
  72. self.presenter?.presenting().present(viewController, animated: animated, completion: completion)
  73. }
  74. }
  75. func openCamera(mode: UIImagePickerController.CameraCaptureMode) {
  76. PermissionHelper.isAllowedToRecordVideo { (isAllowed) in
  77. if isAllowed {
  78. self.openPicker(mode)
  79. } else {
  80. self.presenter?.presenting().alert(message: "camera_access_denied_text", okAction: {
  81. UIApplication.tryURL(url: UIApplication.openSettingsURLString)
  82. })
  83. }
  84. }
  85. }
  86. func openPicker(_ mode: UIImagePickerController.CameraCaptureMode) {
  87. self.imagePicker.sourceType = UIImagePickerController.SourceType.camera
  88. let mediaTypes = ["public.image"]
  89. self.imagePicker.mediaTypes = mediaTypes
  90. self.imagePicker.cameraCaptureMode = mode
  91. self.imagePicker.allowsEditing = false
  92. self.imagePicker.modalPresentationStyle = .overFullScreen
  93. self.imagePicker.delegate = self
  94. counter += 1
  95. // let overlay = createOverlay(view: imagePicker.cameraOverlayView!)
  96. // imagePicker.view.addSubview(overlay)
  97. // if !self.imagePicker.isBeingPresented {
  98. // DispatchQueue.main.async {
  99. // self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
  100. // }
  101. // }
  102. if counter == 1 {
  103. self.presentViewController(viewController: self.imagePicker, animated: true) {
  104. self.counter = 0
  105. }
  106. // self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
  107. }
  108. // }
  109. print("123123123123 \(counter)")
  110. }
  111. func createOverlay(view: UIView) -> UIView {
  112. let overlayView = UIView()
  113. overlayView.frame = CGRect(x: 100, y: 100, width: view.frame.width, height: view.frame.height - 200)
  114. overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
  115. let path = CGMutablePath()
  116. let w = UIScreen.main.bounds.width
  117. let h = UIScreen.main.bounds.height
  118. path.addRoundedRect(in: CGRect(x: 30, y: 200, width: overlayView.frame.width-60, height: overlayView.frame.width - 150), cornerWidth: 5, cornerHeight: 5)
  119. path.closeSubpath()
  120. let shape = CAShapeLayer()
  121. shape.path = path
  122. shape.lineWidth = 5.0
  123. shape.strokeColor = UIColor.white.cgColor
  124. shape.fillColor = UIColor.white.cgColor
  125. overlayView.layer.addSublayer(shape)
  126. path.addRect(CGRect(origin: .zero, size: overlayView.frame.size))
  127. let maskLayer = CAShapeLayer()
  128. maskLayer.backgroundColor = UIColor.black.cgColor
  129. maskLayer.path = path
  130. maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
  131. overlayView.layer.mask = maskLayer
  132. overlayView.clipsToBounds = true
  133. return overlayView
  134. }
  135. private func showPhotoGallery(mode: UIImagePickerController.CameraCaptureMode) {
  136. PermissionHelper.isAllowedToShowGallary { (isAllowed) in
  137. DispatchQueue.main.async {
  138. if isAllowed {
  139. self.imagePicker.allowsEditing = false
  140. self.imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
  141. let mediaTypes = mode == .video ? ["public.image", "public.movie"] : ["public.image"]
  142. self.imagePicker.mediaTypes = mediaTypes
  143. self.imagePicker.modalPresentationStyle = .overFullScreen
  144. self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
  145. } else {
  146. self.presenter?.presenting().alert(
  147. message: "galery_access_denied_text".localized(),
  148. okAction: {
  149. UIApplication.tryURL(url: UIApplication.openSettingsURLString)
  150. }
  151. )
  152. }
  153. }
  154. }
  155. }
  156. func resizeImage(image: UIImage, to targetSize: CGSize) -> UIImage? {
  157. // This is the rect that we've calculated out and this is what is actually used below
  158. let rect = CGRect(origin: CGPoint.zero, size: targetSize)
  159. // Actually do the resizing to the rect using the ImageContext stuff
  160. UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
  161. image.draw(in: rect)
  162. let newImage = UIGraphicsGetImageFromCurrentImageContext()
  163. UIGraphicsEndImageContext()
  164. return newImage
  165. }
  166. }
  167. extension MultiMediaManager: UIImagePickerControllerDelegate {
  168. func imagePickerController(
  169. _ picker: UIImagePickerController,
  170. didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
  171. ) {
  172. let info = Dictionary(uniqueKeysWithValues: info.map {key, value in (key.rawValue, value)})
  173. var completion: (() -> Void)?
  174. if let mediaType = info["UIImagePickerControllerMediaType"] as? String {
  175. if mediaType == "public.image" {
  176. if let picture = info[
  177. UIImagePickerController.InfoKey.originalImage.rawValue
  178. ] as? UIImage {
  179. if let cropsize = self.delegate?.cropSize?() {
  180. if picture.size.width < cropsize.width || picture.size.height < cropsize.height {
  181. let message = "Image size must be greater than \(cropsize.width) X \(cropsize.height)"
  182. self.delegate?.didFinishPickingWithError(error: message)
  183. } else {
  184. guard let resizedImage = self.resizeImage(image: picture, to: cropsize) else { return }
  185. completion = {
  186. self.delegate?.didFinishPickingWithImage?(image: resizedImage)
  187. }
  188. }
  189. } else {
  190. completion = {
  191. self.delegate?.didFinishPickingWithImage?(image: picture)
  192. }
  193. }
  194. }
  195. } else if mediaType == "public.movie" {
  196. // _ = info["UIImagePickerControllerMediaURL"] as! URL
  197. return
  198. }
  199. }
  200. picker.dismiss(animated: true) {
  201. completion?()
  202. }
  203. }
  204. }
  205. extension MultiMediaManager: UINavigationControllerDelegate {
  206. }
  207. struct PermissionHelper {
  208. static func isAllowedToRecordVideo(completion: @escaping (Bool) -> Void) {
  209. let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
  210. completion(status != .denied && status != .restricted)
  211. }
  212. static func isAllowedToRecordSound(completion: @escaping (Bool) -> Void) {
  213. AVAudioSession.sharedInstance().requestRecordPermission(completion)
  214. }
  215. static func isAllowedToShowGallary(completion: @escaping (Bool) -> Void) {
  216. PHPhotoLibrary.requestAuthorization { (status) in
  217. completion(status == .authorized)
  218. }
  219. }
  220. }
  221. struct DevicePlatform {
  222. static var isSimulator: Bool {
  223. #if targetEnvironment(simulator)
  224. // We're on the simulator
  225. return true
  226. #else
  227. // We're on a device
  228. return false
  229. #endif
  230. }
  231. }