Расписание UILocalNotification на основе изменений в основных данных

Я делаю простое приложение с расширением 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() в фоновом режиме.

Я нашел аналогичный вопрос (Планирование локального уведомления из расширения Today), где один ответ предлагает аналогичное решение. В отличие от предыдущего решения, подключение к Интернету не требуется для получения уведомлений, но потребуется подключение к Интернету, чтобы обеспечить актуальность уведомлений при регистрации нового события.

Фоновая выборка

Я подумал об использовании фоновой выборки, чтобы получить что-то произвольное с сервера, а затем запустить файл updateLocalNotificationsFromCoreData(). Это был бы способ запустить обновление в фоновом режиме, хотя кажется глупым извлекать данные, если эти данные не используются, и похоже на то, из-за чего приложение может быть отклонено. Также существует риск того, что система не будет регулярно вызывать фоновое обновление, если пользователь мало открывает приложение и в основном использует виджет «Сегодня».

Использовать фоновые обновления местоположения

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

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


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

Или, если это кажется невозможным, я был бы признателен за отзывы о том, какой подход кажется наиболее целесообразным.


EDIT: я придумал новое решение. Это не идеально, но я думаю, что это лучше, чем другие подходы, которые я рассматривал. Когда кто-то нажимает кнопку, чтобы зарегистрировать событие, я запускаю полное приложение. Это раздражает, потому что у меня есть все данные, которые мне нужны на тот момент, чтобы дать отзыв пользователю и зарегистрировать событие в виджете «Сегодня», не запуская приложение, но, запустив приложение, у меня есть возможность проверить и запланировать локальные уведомления.

Кроме того, в iOS 9 раздражение пользователя немного сведено к минимуму, потому что появится общесистемная кнопка «Назад», которая позволит пользователю легко вернуться к предыдущему приложению после запуска моего приложения из виджета «Сегодня».

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


person gohnjanotis    schedule 01.01.2016    source источник