Access PHPhotoLibrary when an application is in the background

I have NSURLDownloadTaskone that successfully uploads files in the background (large images or video files). And I successfully copy the url and call this function to save my url to the photo file. As you can see, I would like to send UILocalNotificationto notify the user of the completion of the download.

My problem is that while it PHPhotoLibrary.sharedPhotoLibrary().performChangeswill be called while the application is in the background, the block will not be completed. (however, it was triggered by an application returning to the foreground) I tried to comment, grabbing the main thread to see if it helped and what didn't. And I do not want to send a local notification before the completion block, because I want to inform the user about the notification of the success / failure of the download.

I assume that I can send a notification in the method NSURLDownloadDelegateTask. This will allow the user to know that the file was downloaded successfully, but whether it was not possible to save it in their photos. And I would not want to tell my user that their download was successful, and then they could not find it in their photo library.

Here is my code where I access the Photo Library and modify them.

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)
                        }
                    }
                //})
            }
        }
    }
+4
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)
        }
    }
}
+3

Source: https://habr.com/ru/post/1649637/


All Articles