Maintain images preview as per the selection order

This commit is contained in:
Swift Coder
2024-10-17 11:23:02 -04:00
parent 4effaa4324
commit 1925af6897

View File

@@ -20,7 +20,11 @@ struct MediaPicker: UIViewControllerRepresentable {
final class Coordinator: NSObject, PHPickerViewControllerDelegate { final class Coordinator: NSObject, PHPickerViewControllerDelegate {
let parent: MediaPicker var parent: MediaPicker
let dispatchGroup: DispatchGroup = DispatchGroup()
var orderIds: [String] = []
var orderMap: [String: PreUploadedMedia] = [:]
init(_ parent: MediaPicker) { init(_ parent: MediaPicker) {
self.parent = parent self.parent = parent
@@ -32,6 +36,11 @@ struct MediaPicker: UIViewControllerRepresentable {
} }
for result in results { for result in results {
let orderId = result.assetIdentifier ?? UUID().uuidString
orderIds.append(orderId)
dispatchGroup.enter()
if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
result.itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { (item, error) in result.itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { (item, error) in
guard let url = item as? URL else { return } guard let url = item as? URL else { return }
@@ -50,7 +59,7 @@ struct MediaPicker: UIViewControllerRepresentable {
do { do {
try imageData.write(to: destinationURL) try imageData.write(to: destinationURL)
Task { Task {
await self.chooseMedia(.processed_image(destinationURL)) await self.chooseMedia(.processed_image(destinationURL), orderId: orderId)
} }
} }
catch { catch {
@@ -64,13 +73,13 @@ struct MediaPicker: UIViewControllerRepresentable {
url: url, url: url,
fallback: processImage, fallback: processImage,
unprocessedEnum: {.unprocessed_image($0)}, unprocessedEnum: {.unprocessed_image($0)},
processedEnum: {.processed_image($0)} processedEnum: {.processed_image($0)},
) orderId: orderId)
} else { } else {
// Media was taken from camera // Media was taken from camera
result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in result.itemProvider.loadObject(ofClass: UIImage.self) { (image, error) in
if let image = image as? UIImage, error == nil { if let image = image as? UIImage, error == nil {
self.chooseMedia(.uiimage(image)) self.chooseMedia(.uiimage(image), orderId: orderId)
} }
} }
} }
@@ -83,35 +92,48 @@ struct MediaPicker: UIViewControllerRepresentable {
url: url, url: url,
fallback: processVideo, fallback: processVideo,
unprocessedEnum: {.unprocessed_video($0)}, unprocessedEnum: {.unprocessed_video($0)},
processedEnum: {.processed_video($0)} processedEnum: {.processed_video($0)}, orderId: orderId
) )
} }
} }
} }
dispatchGroup.notify(queue: .main) { [weak self] in
guard let self = self else { return }
var arrMedia: [PreUploadedMedia] = []
for id in self.orderIds {
if let media = self.orderMap[id] {
arrMedia.append(media)
self.parent.onMediaPicked(media)
}
}
}
} }
private func chooseMedia(_ media: PreUploadedMedia) {
self.parent.onMediaPicked(media) private func chooseMedia(_ media: PreUploadedMedia, orderId: String) {
self.parent.image_upload_confirm = true self.parent.image_upload_confirm = true
self.orderMap[orderId] = media
self.dispatchGroup.leave()
} }
private func attemptAcquireResourceAndChooseMedia(url: URL, fallback: (URL) -> URL?, unprocessedEnum: (URL) -> PreUploadedMedia, processedEnum: (URL) -> PreUploadedMedia) { private func attemptAcquireResourceAndChooseMedia(url: URL, fallback: (URL) -> URL?, unprocessedEnum: (URL) -> PreUploadedMedia, processedEnum: (URL) -> PreUploadedMedia, orderId: String) {
if url.startAccessingSecurityScopedResource() { if url.startAccessingSecurityScopedResource() {
// Have permission from system to use url out of scope // Have permission from system to use url out of scope
print("Acquired permission to security scoped resource") print("Acquired permission to security scoped resource")
self.chooseMedia(unprocessedEnum(url)) self.chooseMedia(unprocessedEnum(url), orderId: orderId)
} else { } else {
// Need to copy URL to non-security scoped location // Need to copy URL to non-security scoped location
guard let newUrl = fallback(url) else { return } guard let newUrl = fallback(url) else { return }
self.chooseMedia(processedEnum(newUrl)) self.chooseMedia(processedEnum(newUrl), orderId: orderId)
} }
} }
} }
func makeCoordinator() -> Coordinator { func makeCoordinator() -> Coordinator {
Coordinator(self) Coordinator(self)
} }
func makeUIViewController(context: Context) -> PHPickerViewController { func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration(photoLibrary: .shared()) var configuration = PHPickerConfiguration(photoLibrary: .shared())