PHPicker result(s) incomplete

375 Views Asked by At

SwiftUI novice here.

My PHPicker results show a weird behaviour.

Whether I pick one image or several, often the result is empty for a single image or incomplete if multiple images are picked.

Oddities: every image that is missing from a PHPicker session result can be fetched in another session (so the image itself is okay), furthermore it happens that in the next session some images are additionally returned that had been selected in the session before but were missing.

There are no explicit error messages in the console, also the behaviour is completely unpredictable. So let's say I pick 20 images in a session: 9 of them get returned and appended and maybe another 6 of them get returned additionally in the next session without being picked, so there are still 5 images missing which in turn are able to be picked in future sessions.

Further use of the PHPicker results works without problems; dates and paths are sent into Core Data and the images themselves saved to FileManager; this data is then combined in a list view.

I guess it might have to do with the interplay of the 3 parts (date, path, image) I fetch for each image, but I'm at a loss where exactly the problem arises.

struct PhotoPicker: UIViewControllerRepresentable {

@Binding var dates: [Date?]
@Binding var paths: [String?]
@Binding var images: [UIImage?]

@Environment(\.presentationMode) var presentationMode

func makeUIViewController(context: Context) -> PHPickerViewController {
    var config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
    config.filter = .images
    config.selectionLimit = 20
    config.preferredAssetRepresentationMode = .current
    let controller = PHPickerViewController(configuration: config)
    controller.delegate = context.coordinator
    return controller
}

func makeCoordinator() -> PhotoPicker.Coordinator {
    return Coordinator(self)
}

func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
}

class Coordinator: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        parent.presentationMode.wrappedValue.dismiss()
        guard !results.isEmpty else {
            return
        }
        
        print(results)
        
        for result in results {
            
            if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
                
                if let assetId = result.assetIdentifier {
                    let assetResults = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil)
                    
                    result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) {
                        (url, error) in
                        if error != nil {
                            print("error \(error!)");
                        } else {
                            
                            result.itemProvider.loadObject(ofClass: UIImage.self) {
                                (image, error) in
                                if error != nil {
                                    print("error \(error!)");
                                } else {
                                    
                                    if assetResults.firstObject?.creationDate != nil && url?.lastPathComponent != nil && image != nil {
                                        Task { @MainActor in
                                            self.parent.dates.append(assetResults.firstObject?.creationDate)
                                            print(assetResults.firstObject?.creationDate as Any)
                                            self.parent.paths.append(url?.lastPathComponent)
                                            print(url?.lastPathComponent as Any)
                                            self.parent.images.append(image as? UIImage)
                                            print(image as Any)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    private let parent: PhotoPicker
    init(_ parent: PhotoPicker) {
        self.parent = parent
    }
}

}

0

There are 0 best solutions below