photoLibraryDidChange called maximum twice

jI want to observe inserting and removing photos.

So, I called register PHPhotoLibrary in applicationDidEnterBackground

but, photoLibraryDidChange is called only once or twice

How can I ovserve all changes when my app is in background?

Replies

In general, you will not be told about arbitrary changes via PhotoKit while your app is in the background or killed. Instead, registering as a change observer on the PHPhotoLibrary is meant to allow your app to be informed of relevant changes while it's running. PhotoKit determines which changes are "relevant" based on the PHFetchResult instances that exist in your running application. So typically you should be registered as a change observer for the lifetime of fetch results that you want to keep up to date. Registering right when entering the background doesn't really make sense. If you are registered and changes occur while your app is in the background, you'll be told about all relevant changes at once upon re-entering the foreground. A general workflow looks like:
  • Fetch the assets that you care about via some fetch API, like this one to fetch all assets in the library. Maintain a reference to this fetch result (in the object that cares) for as long as you care about observing its contents

  • Register for changes on the PHPhotoLibrary

  • Respond to changes in photoLibraryDidChange. This basically means:

    • Ask the PHChange instance for changes related to your fetch result via this API, which will return nil if the change doesn't involve your fetch result

    • If non-nil, the returned PHFetchResultchangeDetails should tell you exactly what has been inserted/removed/changed

    • Typically, you'll want to discard your existing PHFetchResult and replace it with the change details' fetchResultAfterChanges. Remember, fetch results are effectively immutable arrays so the old instance will become stale if the library changes

Like I mentioned above, when your app re-enters the foreground, you should receive a photoLibraryDidChange message with a change instance that brings your app's fetch results "up-to-date" as opposed to receiving many calls while in the background. Obviously, if your app was killed by the user or the system, this won't be possible as a non-running app doesn't have any active fetch results. Figuring out everything that changed between runs of your app is quite a bit more complicated and may not scale well with library size. If you clarify your use case goals we may be able to help more