How to migrate PHPhotoLibraryChangeObserver to Swift 6?

I have the following code:

extension AssetGridViewController: PHPhotoLibraryChangeObserver {
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        Task { @MainActor in
            guard let changes = changeInstance.changeDetails(for: fetchResult) else { return }
            fetchResult = changes.fetchResultAfterChanges
        }
    }
}

With Swift 6, this generates a compilation error: Main actor-isolated instance method 'photoLibraryDidChange' cannot be used to satisfy nonisolated protocol requirement. The error includes to fix-it suggestions:

  1. Adding nonisolated to the function (nonisolated func photoLibraryDidChange(_ changeInstance: PHChange))
  2. Adding @preconcurrency to the protocol conformance (extension AssetGridViewController: @preconcurrency PHPhotoLibraryChangeObserver {)

Both options generate a runtime error: EXC_BREAKPOINT (code=1, subcode=0x105b7c400). For context, AssetGridViewController is a regular UIViewController.

Any ideas on how to fix this?

Here is a sample project with the issue, in case somebody wants to try it: https://github.com/tovkal/PhotoSwift6

Three things:

  • The doc comments for PHPhotoLibraryChangeObserver make it clear that it’s not called on the main queue.

  • AssetGridViewController is a UIViewController.

  • UIViewController is isolated to the main actor by default.

Given all of the above, this method must be declared as non-isolated:

extension AssetGridViewController: PHPhotoLibraryChangeObserver {
    nonisolated func photoLibraryDidChange(_ changeInstance: PHChange) {
        // your code here
    }
}

You wrote:

Both options generate a runtime error

That’s surprising. If you write the code as its shown above, with the method being empty, do you still see it trap?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How to migrate PHPhotoLibraryChangeObserver to Swift 6?
 
 
Q