Доступ к 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)
}
}
}