Я делаю простое приложение с расширением Today Widget, которое регистрирует события.
Пользователь может нажать кнопку в приложении или соответствующем виджете «Сегодня», чтобы зарегистрировать событие. Эти события сохраняются вместе с Core Data каждый раз, когда кнопка нажимается в любом месте.
Всякий раз, когда в приложении регистрируется новое событие, я запускаю функцию с именем updateLocalNotificationsFromCoreData()
. Он обрабатывает настройку UILocalNotifications на основе самого последнего события в Core Data после очистки соответствующих существующих уведомлений.
Однако, когда из виджета «Сегодня» регистрируется новое событие, я не могу использовать эту функцию, потому что мне нужно зарегистрировать локальное уведомление с помощью UIApplication.sharedApplication().scheduleLocalNotification()
, а UIApplication недоступен в расширении виджета «Сегодня».
Я понимаю, что мне, вероятно, потребуется сделать что-то нетрадиционное или хакерское, чтобы это заработало, поэтому я пытаюсь оценить возможные подходы и найти относительно надежное решение.
По сути, я хочу найти способ, которым я могу вызывать свою функцию updateLocalNotificationsFromCoreData()
сразу же, как только регистрируется новое событие.
Если я не могу делать это каждый раз, когда регистрируется событие, альтернативой может быть периодический (несколько частый) запуск функции updateLocalNotificationsFromCoreData()
другим способом. Вот несколько решений, которые я думал об использовании, но мне не нравится ни одно из них:
Сделайте это в AppDelegate при запуске приложения (или другом изменении состояния)
Один из подходов, о котором я думаю, — запустить мою функцию updateLocalNotificationsFromCoreData()
в AppDelegate где-нибудь, например didFinishLaunchingWithOptions
.
Недостатком является то, что пользователю потребуется периодически открывать приложение. Если бы пользователь не открывал его часто, поведение уведомлений было бы непоследовательным. Я бы предпочел решение, в котором пользователь мог бы взаимодействовать только с виджетом «Сегодня» и надежно получать локальные уведомления, даже не открывая приложение.
Синхронизируйте события с сервером и используйте Push-уведомления
Я думал о синхронизации данных в Core Data с сервером, а затем о настройке Push-уведомлений на телефон пользователя на основе этого.
Мне это не нравится, потому что я хочу, чтобы пользователь по-прежнему мог получать уведомления без подключения к Интернету. Это также приводит к большим дополнительным затратам на синхронизацию данных с сервером.
Пропингуйте сервер и отправьте push-уведомление о доступном содержимом.
Когда кто-то регистрирует событие с помощью виджета, я могу пропинговать сервер. Этот сервер может отправить обратно беззвучное push-уведомление о доступном содержимом, чтобы запустить приложение updateLocalNotificationsFromCoreData()
в фоновом режиме.
Фоновая выборка
Я подумал об использовании фоновой выборки, чтобы получить что-то произвольное с сервера, а затем запустить файл updateLocalNotificationsFromCoreData()
. Это был бы способ запустить обновление в фоновом режиме, хотя кажется глупым извлекать данные, если эти данные не используются, и похоже на то, из-за чего приложение может быть отклонено. Также существует риск того, что система не будет регулярно вызывать фоновое обновление, если пользователь мало открывает приложение и в основном использует виджет «Сегодня».
Использовать фоновые обновления местоположения
Это кажется самым глупым подходом, но я подумал, что все равно упомяну об этом, так как думал об этом. Я мог бы использовать один из режимов фонового обновления местоположения с низкой точностью, чтобы вызвать updateLocalNotificationsFromCoreData()
.
Это потребовало бы от пользователя разрешить местоположение в фоновом режиме, что было бы трудно объяснить. И это потребует от пользователя, по крайней мере, переместиться на несколько блоков, чтобы вызвать функцию, что может привести к непоследовательному взаимодействию с пользователем. Кроме того, по глупой причине это увеличило бы энергопотребление приложения.
Я был бы очень признателен за новые идеи о том, как я мог бы надежно планировать локальные уведомления при изменении основных данных на устройстве, не подключенном к Интернету!
Или, если это кажется невозможным, я был бы признателен за отзывы о том, какой подход кажется наиболее целесообразным.
EDIT: я придумал новое решение. Это не идеально, но я думаю, что это лучше, чем другие подходы, которые я рассматривал. Когда кто-то нажимает кнопку, чтобы зарегистрировать событие, я запускаю полное приложение. Это раздражает, потому что у меня есть все данные, которые мне нужны на тот момент, чтобы дать отзыв пользователю и зарегистрировать событие в виджете «Сегодня», не запуская приложение, но, запустив приложение, у меня есть возможность проверить и запланировать локальные уведомления.
Кроме того, в iOS 9 раздражение пользователя немного сведено к минимуму, потому что появится общесистемная кнопка «Назад», которая позволит пользователю легко вернуться к предыдущему приложению после запуска моего приложения из виджета «Сегодня».
В будущем я могу попробовать решение, в котором один из вышеперечисленных серверных подходов используется при наличии подключения к Интернету, а затем я бы вернулся к этой системе открытия приложения только тогда, когда сетевое подключение недоступно и мне нужно чтобы запланировать локальные уведомления в приложении.