Skip to content
Snippets Groups Projects
Commit b865380e authored by Kateryna Kostiuk's avatar Kateryna Kostiuk
Browse files

conversations: fix image selections with iOS 14

When user allow access only to selected photos, fetching photos
will fail with current UIImagePicker implementation. This patch uses
PHPickerViewController to load files from photo library.

Change-Id: Iee396882d2514eb6fd925f039158605f755c3cf9
parent 172a33c6
Branches
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@
*/
import UIKit
import PhotosUI
import RxSwift
import Reusable
import SwiftyBeaver
......@@ -33,7 +34,7 @@ import MobileCoreServices
// swiftlint:disable type_body_length
class ConversationViewController: UIViewController,
UIImagePickerControllerDelegate, UINavigationControllerDelegate,
UIDocumentPickerDelegate, StoryboardBased, ViewModelBased, MessageAccessoryViewDelegate, ContactPickerDelegate {
UIDocumentPickerDelegate, StoryboardBased, ViewModelBased, MessageAccessoryViewDelegate, ContactPickerDelegate, PHPickerViewControllerDelegate {
let log = SwiftyBeaver.self
......@@ -139,14 +140,14 @@ class ConversationViewController: UIViewController,
func checkPhotoLibraryPermission() {
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
case .authorized, .limited:
self.importImage()
case .denied, .restricted :
self.showNoPermissionsAlert(title: L10n.Alerts.noLibraryPermissionsTitle)
case .notDetermined:
PHPhotoLibrary.requestAuthorization { status in
switch status {
case .authorized:
case .authorized, .limited:
self.importImage()
case .denied, .restricted:
self.showNoPermissionsAlert(title: L10n.Alerts.noLibraryPermissionsTitle)
......@@ -161,13 +162,28 @@ class ConversationViewController: UIViewController,
}
}
func selectItamsFromPhotoLibrary() {
if #available(iOS 14, *) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
var config = PHPickerConfiguration()
config.selectionLimit = 0
let pickerViewController = PHPickerViewController(configuration: config)
pickerViewController.delegate = self
self.present(pickerViewController, animated: true, completion: nil)
}
} else {
self.checkPhotoLibraryPermission()
}
}
@objc
func imageTapped() {
let alert = UIAlertController.init(title: nil,
message: nil,
preferredStyle: .actionSheet)
let pictureAction = UIAlertAction(title: L10n.Alerts.uploadPhoto, style: UIAlertAction.Style.default) {[weak self] _ in
self?.checkPhotoLibraryPermission()
self?.selectItamsFromPhotoLibrary()
}
let recordVideoAction = UIAlertAction(title: L10n.Alerts.recordVideoMessage, style: UIAlertAction.Style.default) {[weak self] _ in
......@@ -256,7 +272,8 @@ class ConversationViewController: UIViewController,
}
func importImage() {
DispatchQueue.main.async {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
......@@ -267,6 +284,43 @@ class ConversationViewController: UIViewController,
}
}
@available(iOS 14, *)
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
results.forEach { (result) in
let imageFileName: String = result.itemProvider.suggestedName ?? "file"
let provider = result.itemProvider
switch self.getAssetTypeFrom(itemProvider: provider) {
case .image:
provider.loadObject(ofClass: UIImage.self) { [weak self] (object, _) in
guard let self = self,
let image = object as? UIImage,
let imageData = image.jpegData(compressionQuality: 90) else { return }
self.viewModel.sendAndSaveFile(displayName: imageFileName + ".jpeg", imageData: imageData)
}
case .video:
provider.loadDataRepresentation(forTypeIdentifier: UTType.movie.identifier) { [weak self] (data, _) in
guard let self = self,
let data = data else { return }
self.viewModel.sendAndSaveFile(displayName: imageFileName + ".mov", imageData: data)
}
default:
break
}
}
}
@available(iOS 14, *)
private func getAssetTypeFrom(itemProvider: NSItemProvider) -> PHAssetMediaType {
if itemProvider.canLoadObject(ofClass: UIImage.self) {
return .image
}
if itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
return .video
}
return .unknown
}
internal func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
......
......@@ -383,13 +383,19 @@ class ConversationViewModel: Stateable, ViewModel {
func recordVideoFile() {
closeAllPlayers()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.stateSubject.onNext(ConversationState.recordFile(conversation: self.conversation.value, audioOnly: false))
}
}
func recordAudioFile() {
closeAllPlayers()
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
self.stateSubject.onNext(ConversationState.recordFile(conversation: self.conversation.value, audioOnly: true))
}
}
func haveCurrentCall() -> Bool {
return self.callService.call(participantHash: self.conversation.value.hash, accountID: self.conversation.value.accountId) != nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment