在应用程序处于后台时访问 PHPhotoLibrary

Posted

技术标签:

【中文标题】在应用程序处于后台时访问 PHPhotoLibrary【英文标题】:Accessing PHPhotoLibrary while app is in the background 【发布时间】:2016-07-30 15:57:59 【问题描述】:

我有一个NSURLDownloadTask,它正在后台成功下载文件(大图像或视频文件)。我成功复制了 url 并调用此函数将我的 url 保存到照片库。如您所见,我想发送UILocalNotification 通知用户他们的下载已完成。

我的问题是,虽然phphotoLibrary.sharedPhotoLibrary().performChanges 会在应用程序处于后台时被调用,但它的完成块不会。 (但是它要求应用程序回到前台)我尝试注释掉抓取主线程以查看是否有帮助,但它没有。而且我不想在完成块之前发送本地通知,因为我想告诉用户下载成功/不成功的通知。

我想我可以通过NSURLDownloadDelegateTask 方法发送通知。这将让用户知道文件已成功下载,但不知道是否成功将其保存到他们的照片中。而且我不想告诉我的用户他们下载成功,然后他们无法在他们的照片库中找到它。

这是我访问和修改照片库的代码。

func saveURLToPhotosLibrary(url: NSURL, fileName: String) 

        if let fileExtension = url.pathExtension 
            PHPhotoLibrary.sharedPhotoLibrary().performChanges(

                let fileUnmanagedIDTag = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil)

                let fileIDTag = fileUnmanagedIDTag?.takeRetainedValue()
                if let fileUTType = fileIDTag 
                    if UTTypeConformsTo(fileUTType, kUTTypeImage) 
                        PHAssetChangeRequest.creationRequestForAssetFromImageAtFileURL(url)
                     else if UTTypeConformsTo(fileUTType, kUTTypeMovie)
                        PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(url)
                    
                 else 
                    print("Error getting type of file from download")
                

            )  (success, error) in
                //dispatch_async(dispatch_get_main_queue(), 

                    if success 
                        print("finished")
                        self.sendLocalNotification(downloadSuccessful: true, error : nil, fileName: fileName)
                     else 
                        if let error = error 
                            self.sendLocalNotification(downloadSuccessful: false, error : error, fileName: fileName)
                        
                    
                //)
            
        
    

【问题讨论】:

【参考方案1】:

好的,找到了我的工作解决方案。发现应用程序在没有代码运行后立即暂停,因此在我的完成处理程序准备好被调用时应用程序被暂停。我使用UIApplications 共享实例来创建一个新的后台任务。这使我的应用程序有足够的时间调用完成处理程序。然后我一收到通知就结束后台任务。

func saveURLToPhotosLibrary(url: NSURL, fileName: String) 

    //Returns id to later be passed into method that ends task.
    let backgroundID : Int = UIApplication.sharedApplication().beginBackgroundTaskWithName("Save to Photo Library Task") 
        print("Background task expired")
    

    if let fileExtension = url.pathExtension 
        PHPhotoLibrary.sharedPhotoLibrary().performChanges(

            let fileUnmanagedIDTag = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil)

            let fileIDTag = fileUnmanagedIDTag?.takeRetainedValue()
            if let fileUTType = fileIDTag 
                if UTTypeConformsTo(fileUTType, kUTTypeImage) 
                    PHAssetChangeRequest.creationRequestForAssetFromImageAtFileURL(url)
                 else if UTTypeConformsTo(fileUTType, kUTTypeMovie)
                    PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(url)
                
             else 
                print("Error getting type of file from download")
            


        )  (success, error) in

                if success 
                    print("finished")
                    self.sendLocalNotification(downloadSuccessful: true, error : nil, fileName: fileName)
                 else 
                    if let error = error 
                        self.sendLocalNotification(downloadSuccessful: false, error : error, fileName: fileName)
                    
                
            //End background task here passing in id of task from earlier.
            UIApplication.sharedApplication().endBackgroundTask(backgroundID)
        
    

【讨论】:

仅供参考,没有人回应的一个原因是因为您的问题被错误地标记为 NSURLDownload,这是一个仅适用于 OS-X 的遗留 API,而不是 NSURLSession。 :-) 是的,我的错我会删除标签。还以为是NSURLDownloadTask

以上是关于在应用程序处于后台时访问 PHPhotoLibrary的主要内容,如果未能解决你的问题,请参考以下文章

当watchOS应用程序使用HKWorkoutSession在后台运行时如何使WCSession可访问

在应用程序处于后台时获取本地通知

后台模式下的 iBeacon 访问

在应用程序后台运行时保持 XMPPStream 处于活动状态

在应用程序处于后台状态时获取数据

应用程序处于后台时状态栏下方的 IOS 文本