Как наблюдать за изменениями библиотеки фотографий, даже когда приложение закрыто? - PullRequest
0 голосов
/ 29 ноября 2018

Мне нужно получать уведомление при съемке фото / видео, даже когда мое приложение закрыто.

Кто-нибудь знает, как такие приложения, как Google Photos, достигают этого в iOS?

Пока чтоЯ реализовал и зарегистрировал PHPhotoLibraryChangeObserver, однако photoLibraryDidChange вызывается только в том случае, если мое приложение работает в фоновом режиме, но не в том случае, если пользователь вручную закрывает приложение.

Реализация PHPhotoLibraryChangeObserver:

import UIKit
import Photos

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, PHPhotoLibraryChangeObserver {

    // ...

    var assetsFetchResult = PHFetchResult<PHAsset>()

    func applicationDidEnterBackground(_ application: UIApplication) {
        PHPhotoLibrary.requestAuthorization { (authorizationStatus) in
            if (authorizationStatus == .authorized){

                assetsFetchResult = getAssets()!

                PHPhotoLibrary.shared().register(self)
            }
        }
    }

    func getAssets() -> PHFetchResult<PHAsset>?{
        return PHAsset.fetchAssets(with: PHFetchOptions())
    }

    func photoLibraryDidChange(_ changeInstance: PHChange) {
        print("photoLibraryDidChange")
        DispatchQueue.main.async {
            let fetchResultChangeDetails = changeInstance.changeDetails(for: self.assetsFetchResult)

            guard (fetchResultChangeDetails) != nil else {
                return
            }

            self.assetsFetchResult = (fetchResultChangeDetails?.fetchResultAfterChanges)!

            let insertedObjects = fetchResultChangeDetails?.insertedObjects

            let changedObjects = fetchResultChangeDetails?.changedObjects

            let removedObjects = fetchResultChangeDetails?.removedObjects

            // ...
        }
    }
}

Я также пытался добиться этого с помощью фоновой выборки.

Сначала я включил возможность фоновой выборки в ProjectНастройки> Возможности> Фоновые режимы.

Затем я протестировал его:

  • Запустив приложение из XCode, затем нажав Отладка> Имитация фоновой выборки
  • Дублирование моегоСхема и включение опции «Запуск из-за события фоновой выборки»

Однако, похоже, нет никаких гарантий относительно того, когда Background Fetch будет вызываться в реальном сценарии, и мне нужно, чтобы он вызывался каккак можно скорее после съемки фото / видео.

https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623125-application

Реализация фонового извлечения:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        
    UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)
    return true
}

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    //if application.backgroundRefreshStatus == .available && application.applicationState == .background {
        if let newData = getNewAssets() {
            newData.enumerateObjects { (object, _, _) in
                if let asset = object as? PHAsset {
                    // ...
                }
            }
            completionHandler(.newData)
            return
        }
    //}
    completionHandler(.noData)
}

func getNewAssets() -> PHFetchResult<PHAsset>?{
    let options = PHFetchOptions()

    if let lastAutoUpload = UserSession.getLastAutoUploadDate(){
        options.predicate = NSPredicate(format: "(modificationDate > %@)", lastAutoUpload as CVarArg)
    }
    return PHAsset.fetchAssets(with: options)
}

Среда: - Swift 4.2- Xcode 10.1 - Тестирование на реальных устройствах: iPhone 6 и iPad Mini 3 (iOS 12)

...