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.

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