iOS запускает код один раз в день

Идея этого приложения очень проста: скачать файл. Однако это приложение предназначено для людей, которые не всегда находятся в пределах досягаемости Интернета, поэтому мне нужно знать, что, скажем, в 9:00 утра, чтобы загрузить файл на жесткий диск. В приложении будет кнопка для выполнения этого вручную, но у меня это уже работает.

Насколько я понимаю, это будет сложно, если это вообще возможно. Я знаю, что iOS не любит многозадачность, но я также знаю, что она поддерживает фоновые функции таймера. Я открыт для любых предложений, которые могут возникнуть у каждого, даже если это означает написание отдельного приложения. Благодарю.

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

Редактировать 2: Я также читал кое-что о внешнем сервере, инициирующем приложение, но оно не дало описания.

5 ответов

Решение

Вот ситуация с фоновым выполнением, уведомлениями, таймерами и т. Д. В связи с тем, что приложение планирует периодическое выполнение некоторых действий.

  1. Приложение не может выполняться в фоновом режиме, если:

    1. Для этого требуется дополнительное время от ОС. Это сделано с помощью beginBackgroundTaskWithExpirationHandler, Apple не указывает (намеренно), как долго это дополнительное время, однако на практике оно составляет около 10 минут.

    2. Приложение имеет фоновый режим, режимы: voip, audio, location, newstand. Даже если у него есть один из этих типов, приложение не может выполняться без каких-либо ограничений. В остальной части обсуждения предполагается, что приложение не имеет фонового режима.

  2. Когда приложение приостановлено, оно не может сделать НИЧЕГО, чтобы пробудить себя напрямую. Ранее он не мог запланировать NSTimer, он не может использовать что-то вроде executeSelector:afterDelay. и т.п.

    Единственный способ, которым приложение может снова стать активным, - это если ПОЛЬЗОВАТЕЛЬ делает что-то, чтобы сделать его активным. Пользователь может сделать это с помощью следующего:

    1. Запустите приложение прямо с его иконки

    2. Запустите приложение в ответ на локальное уведомление, которое ранее было запланировано приложением, пока оно было активным.

    3. Запустите приложение в ответ на удаленное уведомление, отправленное сервером.

    4. Несколько других: например, запуск URL, если приложение зарегистрировано для запуска через URL; или если он зарегистрирован для работы с определенным типом контента.

Если приложение находится на переднем плане, когда запускается локальное / удаленное уведомление, приложение получает его напрямую.

Если приложение в данный момент не находится на переднем плане, когда запускается локальное / удаленное уведомление, приложение НЕ получает его. Нет кода, который выполняется при срабатывании уведомления!

Только если пользователь выберет уведомление, приложение станет активным и сможет его выполнить.

Обратите внимание, что пользователь может отключить уведомления, либо для всего устройства, либо только для конкретного приложения, и в этом случае пользователь никогда не увидит их. Если устройство отключено, когда уведомление вызвано пожаром, оно теряется.

Вы можете использовать локальные уведомления. Они выполняют код, когда пользователь открывает представленное уведомление. Вы можете настроить локальное уведомление на повторение через заданный интервал (например, ежедневно, ежечасно, еженедельно и т. Д.). Это все еще требует, чтобы пользователь открыл приложение, чтобы начать процесс.

Ссылка на класс UILocalNotification

После запуска метода делегата у вас есть всего несколько секунд для выполнения кода. Зарегистрируйтесь для выполнения длительной фоновой задачи и загрузите все, что вам нужно. Если загрузка не может быть завершена в течение 10 минут, которые вы получаете для выполнения задания, вам необходимо пересмотреть свою стратегию загрузки.

Многозадачность и фоновая обработка Apple

Мы используем эту же концепцию в приложениях для iOS, где я работаю, так что это сработает, если вы настроите все правильно.

ОБНОВИТЬ

Для тех, кому интересно, как это будет работать, вам просто нужно реализовать методы делегата UILocalNotification. Они наследуются от UIApplicationDelegate, который уже должен быть на месте.

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// start your long running bg task here and update your file

}

** ОБНОВЛЕНИЕ 2 **

Ответ Мартина Х пока самый правильный. Но возникает вопрос: если пользователь никогда не открывает приложение, какой смысл скачивать данные, которые он никогда не увидит? Повторяющееся локальное уведомление, напоминающее им об открытии приложения и обновлении, может быть лучшим способом, но все же требует, чтобы пользователь взаимодействовал с вашим приложением, если он хочет, чтобы оно оставалось актуальным и актуальным.

Я почти уверен, что это невозможно, в большинстве случаев вы можете отправлять push-уведомления пользователю, чтобы он обновлялся вручную при необходимости.

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

Что вы можете сделать, это установить NSUserDefault с датой последней загрузки. При запуске проверьте сохраненную дату, если дата не является текущей, и она наступила после 9:00, начните загрузку программно.

Вы пробовали следующее?

if ([[[UIDevice currentDevice] systemVersion] floatValue] >=7.0)
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:600];


- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    completionHandler(UIBackgroundFetchResultNewData);
}
Другие вопросы по тегам