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.

204 lines
6.8 KiB

6 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. init(presenter: MultimediaPresenterProtocol) {
  26. self.presenter = presenter
  27. super.init()
  28. imagePicker.delegate = self
  29. imagePicker.allowsEditing = true
  30. }
  31. func openCameraPicker() {
  32. self.openCamera(mode: .photo)
  33. }
  34. func openPicker(mode: UIImagePickerController.CameraCaptureMode) {
  35. var presentationStyle: UIAlertController.Style = .actionSheet
  36. if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad) {
  37. presentationStyle = .alert
  38. }
  39. let alertController = UIAlertController(
  40. title: nil,
  41. message: "Gme would like to access your camera",
  42. preferredStyle: presentationStyle
  43. )
  44. let cameraAction = UIAlertAction(
  45. title: "camera_text".localized(),
  46. style: UIAlertAction.Style.default
  47. ) { (_) in
  48. self.openCamera(mode: .photo)
  49. }
  50. let galleryAction = UIAlertAction(
  51. title: "gallery_text".localized(),
  52. style: UIAlertAction.Style.default
  53. ) { (_) in
  54. self.showPhotoGallery(mode: mode)
  55. }
  56. let cancelAction = UIAlertAction(title: "cancel_text".localized(), style: .cancel, handler: nil)
  57. alertController.addAction(cameraAction)
  58. alertController.addAction(galleryAction)
  59. alertController.addAction(cancelAction)
  60. alertController.modalPresentationStyle = .overFullScreen
  61. self.presentViewController(viewController: alertController, animated: true, completion: nil)
  62. }
  63. private func presentViewController(
  64. viewController: UIViewController,
  65. animated: Bool,
  66. completion: (() -> Void)?
  67. ) {
  68. OperationQueue.main.addOperation {
  69. self.presenter?.presenting().present(viewController, animated: animated, completion: completion)
  70. }
  71. }
  72. func openCamera(mode: UIImagePickerController.CameraCaptureMode) {
  73. func openPicker() {
  74. self.imagePicker.sourceType = UIImagePickerController.SourceType.camera
  75. let mediaTypes = ["public.image"]
  76. self.imagePicker.mediaTypes = mediaTypes
  77. self.imagePicker.cameraCaptureMode = mode
  78. self.imagePicker.allowsEditing = false
  79. self.imagePicker.modalPresentationStyle = .overFullScreen
  80. self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
  81. }
  82. PermissionHelper.isAllowedToRecordVideo { (isAllowed) in
  83. if isAllowed {
  84. openPicker()
  85. } else {
  86. self.presenter?.presenting().alert(message: "camera_access_denied_text", okAction: {
  87. UIApplication.tryURL(url: UIApplication.openSettingsURLString)
  88. })
  89. }
  90. }
  91. }
  92. private func showPhotoGallery(mode: UIImagePickerController.CameraCaptureMode) {
  93. PermissionHelper.isAllowedToShowGallary { (isAllowed) in
  94. DispatchQueue.main.async {
  95. if isAllowed {
  96. self.imagePicker.allowsEditing = false
  97. self.imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
  98. let mediaTypes = mode == .video ? ["public.image", "public.movie"] : ["public.image"]
  99. self.imagePicker.mediaTypes = mediaTypes
  100. self.imagePicker.modalPresentationStyle = .overFullScreen
  101. self.presentViewController(viewController: self.imagePicker, animated: true, completion: nil)
  102. } else {
  103. self.presenter?.presenting().alert(
  104. message: "galery_access_denied_text".localized(),
  105. okAction: {
  106. UIApplication.tryURL(url: UIApplication.openSettingsURLString)
  107. }
  108. )
  109. }
  110. }
  111. }
  112. }
  113. func resizeImage(image: UIImage, to targetSize: CGSize) -> UIImage? {
  114. // This is the rect that we've calculated out and this is what is actually used below
  115. let rect = CGRect(origin: CGPoint.zero, size: targetSize)
  116. // Actually do the resizing to the rect using the ImageContext stuff
  117. UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
  118. image.draw(in: rect)
  119. let newImage = UIGraphicsGetImageFromCurrentImageContext()
  120. UIGraphicsEndImageContext()
  121. return newImage
  122. }
  123. }
  124. extension MultiMediaManager: UIImagePickerControllerDelegate {
  125. func imagePickerController(
  126. _ picker: UIImagePickerController,
  127. didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
  128. ) {
  129. let info = Dictionary(uniqueKeysWithValues: info.map {key, value in (key.rawValue, value)})
  130. var completion: (() -> Void)?
  131. if let mediaType = info["UIImagePickerControllerMediaType"] as? String {
  132. if mediaType == "public.image" {
  133. if let picture = info[
  134. UIImagePickerController.InfoKey.originalImage.rawValue
  135. ] as? UIImage {
  136. if let cropsize = self.delegate?.cropSize?() {
  137. if picture.size.width < cropsize.width || picture.size.height < cropsize.height {
  138. let message = "Image size must be greater than \(cropsize.width) X \(cropsize.height)"
  139. self.delegate?.didFinishPickingWithError(error: message)
  140. } else {
  141. guard let resizedImage = self.resizeImage(image: picture, to: cropsize) else { return }
  142. completion = {
  143. self.delegate?.didFinishPickingWithImage?(image: resizedImage)
  144. }
  145. }
  146. } else {
  147. completion = {
  148. self.delegate?.didFinishPickingWithImage?(image: picture)
  149. }
  150. }
  151. }
  152. } else if mediaType == "public.movie" {
  153. // _ = info["UIImagePickerControllerMediaURL"] as! URL
  154. return
  155. }
  156. }
  157. picker.dismiss(animated: true) {
  158. completion?()
  159. }
  160. }
  161. }
  162. extension MultiMediaManager: UINavigationControllerDelegate {
  163. }
  164. struct PermissionHelper {
  165. static func isAllowedToRecordVideo(completion: @escaping (Bool) -> Void) {
  166. let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
  167. completion(status != .denied && status != .restricted)
  168. }
  169. static func isAllowedToRecordSound(completion: @escaping (Bool) -> Void) {
  170. AVAudioSession.sharedInstance().requestRecordPermission(completion)
  171. }
  172. static func isAllowedToShowGallary(completion: @escaping (Bool) -> Void) {
  173. PHPhotoLibrary.requestAuthorization { (status) in
  174. completion(status == .authorized)
  175. }
  176. }
  177. }