Доступ к PHPhotoLibrary, пока приложение находится в фоновом режиме

У меня есть 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)
        }
    }
}
Другие вопросы по тегам