PHPhotoLibraryChangeObserver scheint seit dem letzten Xcode Probleme zu haben

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • PHPhotoLibraryChangeObserver scheint seit dem letzten Xcode Probleme zu haben

    Hallo,

    seit dem letzten Xcode Update funktioniert mein PHPhotoLibraryChangeObserver nicht mehr wie er soll. Wird die App zum ersten mal gestartet, wird der User nach Zugriff auf das Photo Album gefragt. Nachdem der User den Zugriff erlaubt hat, will ich die neuen fetch Ergebnisse über den PHPhotoLibraryChangeObserver sehen. Das funktioniert nur leider nicht mehr, so dass beim ersten Start keine Bilder im Album angezeigt werden. Erst bei einem erneutem öffnen der App funktioniert alles wie es soll und die Bilder werden angezeigt...

    Mein Code dazu sieht wie folgt aus:

    Quellcode

    1. extension MIPCollectionViewController: PHPhotoLibraryChangeObserver {
    2. func photoLibraryDidChange(_ changeInstance: PHChange) {
    3. print(changeInstance.changeDetails(for: fetchResult))
    4. guard let changes = changeInstance.changeDetails(for: fetchResult)
    5. else { return }
    6. DispatchQueue.main.sync {
    7. fetchResult = changes.fetchResultAfterChanges
    8. if changes.hasIncrementalChanges {
    9. guard let collectionView = self.collectionView else { fatalError() }
    10. collectionView.performBatchUpdates({
    11. if let removed = changes.removedIndexes, !removed.isEmpty {
    12. collectionView.deleteItems(at: removed.map({ IndexPath(item: $0, section: 0) }))
    13. }
    14. if let inserted = changes.insertedIndexes, !inserted.isEmpty {
    15. collectionView.insertItems(at: inserted.map({ IndexPath(item: $0, section: 0) }))
    16. }
    17. changes.enumerateMoves { fromIndex, toIndex in
    18. collectionView.moveItem(at: IndexPath(item: fromIndex, section: 0),
    19. to: IndexPath(item: toIndex, section: 0))
    20. }
    21. })
    22. if let changed = changes.changedIndexes, !changed.isEmpty {
    23. collectionView.reloadItems(at: changed.map({ IndexPath(item: $0, section: 0) }))
    24. }
    25. } else {
    26. collectionView.reloadData()
    27. }
    28. resetCachedAssets()
    29. }
    30. }
    31. }
    Alles anzeigen


    Ich habe die Fehlerquelle auch schon ausgemacht, jedoch verstehe ich sie nicht. Die changeDetails geben immer wieder nil aus. Man könnte jetzt meinen das sich beim fetchen einfach nichts im Photo Album ändert, dass kann aber nicht sein. Hat vorher ja auch funktioniert. Aber ich verstehe halt nicht wieso ich hierbei dann einen nil Wert bekomme...


    Quellcode

    1. guard let changes = changeInstance.changeDetails(for: fetchResult)
    2. else { return }


    In meiner viewDidLoad() habe ich dann auch noch folgenden Code um den Observer aufzurufen:


    Quellcode

    1. if fetchResult == nil {
    2. PHPhotoLibrary.shared().register(self)
    3. let allPhotosOptions = PHFetchOptions()
    4. allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    5. fetchResult = PHAsset.fetchAssets(with: allPhotosOptions)
    6. print(fetchResult)
    7. }
    Hat jemand vielleicht ne Idee was ich hier ausprobieren könnte oder wo das Problem liegt ? Selbst das Apple Beispiel Projekt funktioniert nicht mehr developer.apple.com/documentat…n_image_picker_controller
  • Es gibt keine requestAuthorization(_:) Funktion in meinem Code. Die Authorization Anfrage kommt über die Info.plist. register(_:) wird stand jetzt in der viewDidLoad() aufgerufen. Aber wie gesagt, der Observer meldet sich erst nachdem der User nach Zugriff gefragt wurde, egal an welcher stelle ich register(_:) aufrufe.

    Der erste fetchResult sieht demnach immer wie folgt aus:
    Optional(<PHUnauthorizedFetchResult: 0x600001509b00> count=(NA))

    Was kann ich mir noch anschauen wenn ich keine requestAuthorization(_:) Funktion habe ?
  • Also hab ich jetzt mal ausprobiert, habe den Code in der viewDidAppear und der viewDidLoad ausprobiert:

    Quellcode

    1. let status = PHPhotoLibrary.authorizationStatus()
    2. switch status {
    3. case .authorized: print("authorized")
    4. case .denied, .restricted : print("denied")
    5. case .notDetermined:
    6. print("notDetermined")
    7. PHPhotoLibrary.requestAuthorization() { (status) -> Void in
    8. switch status {
    9. case .authorized: PHPhotoLibrary.shared().register(self)
    10. case .denied, .restricted: print("denied")
    11. case .notDetermined: break
    12. }
    13. }
    14. }
    Alles anzeigen


    Bringt aber rein gar nichts da der Observer sich dadurch gar nicht mehr angesprochen fühlt. Also wenn man das ganz logisch betrachtet dann muss doch noch bevor der User nach der Authorization gefragt wird, der Observer registriert werden damit dieser reagieren kann wenn das erste mal gefetched wird oder nicht ?

    Habe die viewDidLoad also so aufgebaut:


    Quellcode

    1. override func viewDidLoad() {
    2. PHPhotoLibrary.shared().register(self)
    3. if fetchResult == nil {
    4. let allPhotosOptions = PHFetchOptions()
    5. allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    6. fetchResult = PHAsset.fetchAssets(with: allPhotosOptions)
    7. print(fetchResult)
    8. }
    9. }
    Doch egal was ich tue, der Observer sagt mir print(changeInstance.changeDetails(for: fetchResult)) == nil. Das macht doch absolut keinen Sinn ?

    Ich habe dann sogar nochmal ausprobiert was wäre wenn der Code so ausschauen würde:



    Quellcode

    1. let status = PHPhotoLibrary.authorizationStatus()
    2. switch status {
    3. case .authorized: print("authorized")
    4. case .denied, .restricted : print("denied")
    5. case .notDetermined:
    6. print("notDetermined")
    7. PHPhotoLibrary.requestAuthorization() { (status) -> Void in
    8. switch status {
    9. case .authorized:
    10. let allPhotosOptions = PHFetchOptions()
    11. allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    12. self.fetchResult = PHAsset.fetchAssets(with: allPhotosOptions)
    13. print(self.fetchResult)
    14. case .denied, .restricted: print("denied")
    15. case .notDetermined: break
    16. }
    17. }
    18. }
    Alles anzeigen


    Doch trotzdem wird im Observer keine fetch Änderung wahrgenommen und es wird nil ausgegeben. Was verstehe ich falsch, zumal es sonst immer funktioniert hat ?