Skip to content

Commit

Permalink
fix: Picking ProRAW pictures from Gallery
Browse files Browse the repository at this point in the history
If object can't be loaded, load its data representation.
Considering that the code was duplicated for multiple and single selections, refactor the code to remove redundancy.
For multiple selection, since it's not possible to cancel image loading when one fails, the refactor also changes concurrent loading to serial.

References: https://outsystemsrd.atlassian.net/browse/RMET-3243
  • Loading branch information
OS-ricardomoreirasilva committed May 9, 2024
1 parent 9634552 commit 1eb5e46
Showing 1 changed file with 46 additions and 44 deletions.
90 changes: 46 additions & 44 deletions camera/ios/Sources/CameraPlugin/CameraPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,59 +256,61 @@ extension CameraPlugin: UIImagePickerControllerDelegate, UINavigationControllerD
extension CameraPlugin: PHPickerViewControllerDelegate {
public func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion: nil)
guard let result = results.first else {

guard !results.isEmpty else {
self.call?.reject("User cancelled photos app")
return
}
if multiple {
var images: [ProcessedImage] = []
var processedCount = 0
for img in results {
guard img.itemProvider.canLoadObject(ofClass: UIImage.self) else {
self.call?.reject("Error loading image")
return
}
// extract the image
img.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (reading, _) in
if let image = reading as? UIImage {
var asset: PHAsset?
if let assetId = img.assetIdentifier {
asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil).firstObject
}
if let processedImage = self?.processedImage(from: image, with: asset?.imageData) {
images.append(processedImage)
}
processedCount += 1
if processedCount == results.count {
self?.returnImages(images)
}
} else {
self?.call?.reject("Error loading image")
}
}
}

} else {
guard result.itemProvider.canLoadObject(ofClass: UIImage.self) else {
self.call?.reject("Error loading image")

self.fetchProcessedImages(from: results) { [weak self] processedImageArray in
guard let processedImageArray else {
self?.call?.reject("Error loading image")
return
}
// extract the image
result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] (reading, _) in
if let image = reading as? UIImage {
var asset: PHAsset?
if let assetId = result.assetIdentifier {
asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil).firstObject
}
if var processedImage = self?.processedImage(from: image, with: asset?.imageData) {
processedImage.flags = .gallery
self?.returnProcessedImage(processedImage)
return

if self?.multiple == true {
self?.returnImages(processedImageArray)
} else if var processedImage = processedImageArray.first {
processedImage.flags = .gallery
self?.returnProcessedImage(processedImage)
}
}
}

private func fetchProcessedImages(from pickerResultArray: [PHPickerResult], accumulating: [ProcessedImage] = [], _ completionHandler: @escaping ([ProcessedImage]?) -> Void) {
func loadImage(from pickerResult: PHPickerResult,_ completionHandler: @escaping (UIImage?) -> Void) {
let itemProvider = pickerResult.itemProvider
if itemProvider.canLoadObject(ofClass: UIImage.self) {
// extract the image
itemProvider.loadObject(ofClass: UIImage.self) { itemProviderReading, _ in
completionHandler(itemProviderReading as? UIImage)
}
} else {
// extract the image's data representation
itemProvider.loadDataRepresentation(forTypeIdentifier: UTType.image.identifier) { data, _ in
guard let data else {
return completionHandler(nil)
}
completionHandler(UIImage(data: data))
}
self?.call?.reject("Error loading image")
}
}

guard let currentPickerResult = pickerResultArray.first else { return completionHandler(accumulating) }

loadImage(from: currentPickerResult) { [weak self] loadedImage in
guard let self, let loadedImage else { return completionHandler(nil) }
var asset: PHAsset?
if let assetId = currentPickerResult.assetIdentifier {
asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil).firstObject
}
let newElement = self.processedImage(from: loadedImage, with: asset?.imageData)
self.fetchProcessedImages(
from: Array(pickerResultArray.dropFirst()),
accumulating: accumulating + [newElement],
completionHandler
)
}
}
}

Expand Down

0 comments on commit 1eb5e46

Please sign in to comment.