Расширение действия — несколько NSURLSession

Я пытаюсь загрузить изображения из приложения Photo через расширение действия. Я использую NSURLSession для загрузки в фоновом режиме. Вот код, который я использую.

var configName = "com.myapp.uploadImage"
var config  = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(configName)
config.sharedContainerIdentifier = "group.myApp.sample"

var session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request)
task.resume()

self.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)

Это работает нормально.

Вопрос в том, когда я загружаю изображение и закрываю представление один раз, а затем снова пытаюсь загрузить второе изображение, пока первоначальный процесс все еще выполняется в фоновом режиме, начальная NSURLSession не завершена. Завершается только второй процесс. Короче говоря, вторая сессия преодолевает первую сессию.

Я попытался использовать NSOperationQueue. Но расширение действия после закрытия и открытия снова для второго сеанса просто создает новую NSOperationQueue, и, следовательно, проблема все еще сохраняется.

Любое предложение будет полезно. Заранее спасибо.


person Shob-Z    schedule 05.12.2014    source источник


Ответы (1)


Убедитесь, что вы не пытаетесь создать второй фоновый сеанс с тем же идентификатором, пока первый все еще работает. Сохраните фоновый сеанс, чтобы использовать его позже.

В качестве «Вопросов фонового сеанса» документа Руководство по системному программированию загрузки URL: Использование NSURLSession говорит:

Примечание. Вы должны создать ровно один сеанс для каждого идентификатора (указывается при создании объекта конфигурации). Поведение нескольких сеансов, использующих один и тот же идентификатор, не определено.

Обратите внимание, что в этом документе также упоминается, что необходимо указать и реализовать делегат. (По крайней мере, как вы узнаете об ошибке, если не сделаете этого?) Пример, представленный в разделе Выполнение загрузки и загрузки на сайте Руководство по программированию расширения приложения также указывает делегата.

Кроме того, реализовал ли делегат приложения вашего основного приложения метод handleEventsForBackgroundURLSession? Вы должны захватить completionHandler и вызвать его, когда вызывается метод NSURLSessionDelegate URLSessionDidFinishEventsForBackgroundURLSession.

Наконец, я заметил, что вы используете задачу данных. В документации NSURLSession указано, что нельзя использовать задачи данных с фоновыми сеансами, а только задачи загрузки/выгрузки. Я всегда предполагал, что это было просто для того, чтобы вы не пытались использовать метод didReceiveData делегата, но я мог бы попробовать использовать задачу загрузки на тот случай, если есть какая-то другая проблема, связанная с задачами данных с фоновыми сеансами.

person Rob    schedule 05.12.2014
comment
Пробовал использовать разные идентификаторы. Все та же проблема. - person Shob-Z; 05.12.2014
comment
Кроме того, методы делегирования не будут полезны. Как говорится в рекомендациях Apple, мы должны закрыть расширение действия и запустить nsurlsession в фоновом режиме. Поэтому, когда расширение действия отклоняется, делегат тоже уничтожается. - person Shob-Z; 05.12.2014
comment
Я долгое время выполнял nsurlsessions внутри приложения. И каждый раз это работало нормально. Но у расширения действия есть руководство, и оно звучит разумно. - person Shob-Z; 05.12.2014
comment
В примере в Руководстве по программированию расширений приложений указан делегат, поэтому я бы тоже предпочел. Если ничего другого (а) он говорит, что это требуется для фоновых сеансов; и (б) существует механизм сообщения об ошибках, которым вы не пользуетесь. И в том же руководстве говорится, что если ваше расширение не работает, когда запрос завершается, оно вызывает handleEventsForBackgroundURLSession в основном приложении, поэтому ваше приложение также должно обрабатывать это (и для этого, безусловно, требуется делегат). - person Rob; 05.12.2014