即使关闭应用程序,如何观察照片库的变化?

时间:2018-11-29 11:35:13

标签: ios swift background-fetch phphotolibrary

即使在我的应用程序关闭的情况下,拍摄照片/录像时也需要通知我。

有人知道Google相册之类的应用如何在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

            // ...
        }
    }
}

我也尝试通过后台抓取来实现这一目标。

首先,我在“项目设置”>“功能”>“后台模式”中启用了后台获取功能。

然后我通过以下方式对其进行了测试:

  • 从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)
}

环境: -迅捷4.2 -Xcode 10.1 -在真实设备上进行测试:iPhone 6和iPad Mini 3(iOS 12)

0 个答案:

没有答案