Невозможно вызвать URLSessionTaskDelegate#willBeginDelayedRequest, несмотря ни на что

Что бы я ни делал, willBeginDelayedRequest не вызывается. Другие вызовы делегатов работают отлично.

Обратите внимание, что это даже не фоновое приложение, это простой случай...

  • запустите приложение
  • убить подключение к интернету
  • теперь отправьте свой вызов API или что-то еще
  • см. сообщение «А»
  • позже включи интернет
  • см. сообщение «С»
  • :( вы никогда не увидите сообщение "B"

Я видел такое поведение во многих проектах. Как заставить willBeginDelayedRequest работать??

Делегат...

class Main: UIViewController, CLLocationManagerDelegate, URLSessionTaskDelegate {

код ..

func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
    print("(A) works perfectly - phone was offline when task was started")
}

// Doesn't seem to work ...
func urlSession(_ session: URLSession, task: URLSessionTask, willBeginDelayedRequest request: URLRequest, completionHandler: @escaping (URLSession.DelayedRequestDisposition, URLRequest?) -> Void) {
    print("(B) this is never called, even when the command completes perfectly :/")
}

установка делегата...

let cfg = URLSessionConfiguration.default
cfg.waitsForConnectivity = true
let task = URLSession(configuration: cfg).dataTask(with: request) { [weak self] (data, response, error) in
    ...
    ...
    print("(C) after net restored, this runs flawlessly")
}
task.delegate = ..
task.resume()

«Обратите внимание, что этого нет даже в приложении с поддержкой фонового режима» противоречит обсуждению этого метода: «Этот метод вызывается, когда выполняется задача фонового сеанса с отложенным временем запуска». Другой (тот, который «работает») говорит: «Он никогда не вызывается для фоновых сеансов, потому что waitsForConnectivity игнорируется для этих сеансов», поэтому такое поведение кажется нормальным.

Larme 06.05.2024 15:14

ах! Думаю, ты решил головоломку @Larme !! Спасибо. Возможно, стоит дать ответ для гуглеров? Казалось бы, НЕТ вызова, сообщающего вам, что в нефоновом случае он «начался снова» - вы случайно не знаете, так ли это? ТС снова

Fattie 06.05.2024 16:15

Вы ищете доступность (т. е. знаете, когда вернетесь к «подключению к Интернету»)?

Larme 06.05.2024 16:32

ура @Larme, нет, мы используем это в большинстве проектов. Когда я создаю URLSessionDataTask , он сообщит мне (очевидно, через делегата), когда/если возникла проблема с отправкой. Я хочу, чтобы он сообщил мне, когда он снова установил соединение (и/или, неявно, когда он снова попытается и/или поверит, что теперь это возможно).

Fattie 06.05.2024 17:24

{В некоторых случаях это можно сделать небрежно с помощью .progress, но на самом деле это не ответ.)

Fattie 06.05.2024 17:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Важная часть вашего сценария: не в фоновом режиме.

В документе urlSession(_:task:willBeginDelayedRequest:completionHandler:) говорится:

Этот метод вызывается, когда задача фонового сеанса с задержкой время начала (установленное в свойстве EarlyBeginDate) готово к начинать. Этот метод делегата следует реализовывать только в том случае, если запрос может устареть во время ожидания загрузки сети, и его необходимо заменен новым запросом. Чтобы загрузка продолжилась, делегат должен вызовите обработчик завершения, передав расположение, которое указывает как должна выполняться задача. Прохождение Расположение URLSession.DelayedRequestDisposition.cancel эквивалентно для непосредственного вызова метода cancel() для задачи.

В документе urlSession(_:taskIsWaitingForConnectivity:) говорится:

Этот метод вызывается не более одного раза для каждой задачи и только в том случае, если соединение изначально недоступно. Это никогда не требуется фоновые сеансы, поскольку waitsForConnectivity игнорируется для эти сеансы.

Это должно объяснить, почему в вашем тесте вызывается метод URLSessionTaskDelegate, а urlSession(_:taskIsWaitingForConnectivity:) — нет.

Другие вопросы по теме