Планирование локального уведомления в рамках расширения Today

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

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

UIApplication.sharedApplication().scheduleLocalNotification(notification)

который, к сожалению, полагается на UIApplication.sharedApplication(), который недоступен из расширения.

Итак, мой вопрос: Как назначить локальное уведомление из внутреннего расширения?

Как ни странно, я могу создать фреймворк с кодом, разделяемым между моим приложением и моим расширением, и в этой структуре я могу позвонить:

func schedule() {
    // ...
    let settings = UIUserNotificationSettings(forTypes: .Sound | .Alert, categories: nil)
    UIApplication.sharedApplication().registerUserNotificationSettings(settings)
    // ...
    UIApplication.sharedApplication().scheduleLocalNotification(notification)
    // ...
}

Если я затем импортирую эту фреймворк из моего расширения и вызываю schedule(), я получаю этот вывод:

Failed to inherit CoreMedia permissions from 13636: (null)

Attempting to schedule a local notification <UIConcreteLocalNotification: 0x7feaf3657a00>{fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, user info = (null)} with an alert but haven't received permission from the user to display alerts

Attempting to schedule a local notification <UIConcreteLocalNotification: 0x7feaf3657a00>{fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, November 1, 2014 at 1:01:48 PM Western European Standard Time, user info = (null)} with a sound but haven't received permission from the user to play sounds

Таким образом, модуль, работающий в расширении, имеет доступ к UIApplication.sharedApplication(), так как этот код на самом деле пытается запланировать уведомление, но система не готова к расширению, запрашивая разрешения на отображение предупреждений и, следовательно, сбой (что то, что кажется в любом случае).

Как я могу это решить?

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

Ответ 1

Я думаю, что это может стать возможным, если вы это сделаете:

  • Всякий раз, когда вы хотите запланировать локальное уведомление, сделайте свое сегодняшнее расширение создайте уведомление и напишите его в файл в совместно используемом контейнере.

  • (Вам нужен сервер). Обратитесь к своему серверу с помощью своего сегодняшнего внутреннего номера, попросите своего сервера отправить извещенное push-уведомление (content-available: 1), которое затем разбудит ваше основное приложение.

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

Ответ 2

Если кто-нибудь приходит к этому вопросу, это теперь можно реализовать в iOS 10 и новой платформе UserNotifications. Чтобы запланировать локальное уведомление из вашего расширения приложения, вы можете просто вызвать эту строку кода из вашего внутреннего номера:

UNUserNotificationCenter.current().add(<#UNNotificationRequest#>)

Ответ 3

Это крайне маловероятно. Расширениям приложений не разрешается доступ к sharedApplication. Тот факт, что это позволяет предотвратить компилятор, замечая, что вы это делаете, не меняет этого. Если вы попробуете это в отладчике, я бы предположил, что sharedApplication на самом деле возвращает nil и что поэтому код не работает.

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