iOS10 UNNotificationServiceExtension не вызывается

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

Я сделал все, что указано на официальных сайтах и ​​в некоторых других местах:

  • У меня запущено приложение с push-уведомлениями и правильным профилем обеспечения
  • Я добавил новую цель в свое приложение, расширение службы уведомлений
  • Реализовал мой собственный код (на самом деле это не имеет значения, потому что даже не входит в новый класс)
  • Также мне пришлось установить профиль обеспечения для этого расширения, я просто использую профиль с подстановочным знаком, я не вижу никакой документации, указывающей, должна ли цель расширения включать функцию push-уведомлений, в этом случае мне понадобится специальная подготовка для этого Во-первых, в данный момент я просто использую подстановочный знак prov, в любом случае он соответствует (должен совпадать) профилю, который я использую в цели приложения, а функция push-уведомлений включена только для цели приложения.
  • Я добавил UNNotificationExtensionCategory и NSExtensionPointIdentifier. Также я отправляю категорию как часть полезной нагрузки с сервера.

Как я уже сказал, я получаю уведомление, но никогда не проходит через расширение. Я вижу, как ОС пытается загрузить расширение, но затем выдает ошибку без соответствующего описания для выявления проблемы:

Dec 31 21:00:00 iPhone SpringBoard(libextension.dylib)[51] <Notice>: calling plugIn beginUsing:   
Dec 31 21:00:57 iPhone pkd[86] <Notice>: assigning plug-in com.test.app.NotificationWithAttachmentExtension(1.0) to plugin sandbox   
Dec 31 21:03:57 iPhone pkd[86] <Notice>: enabling pid=51 for plug-in com.test.app.NotificationWithAttachmentExtension(1.0) 38BB5FF1-2597-42E0-B950-169DBFA80573 /private/var/containers/Bundle/Application/A8C47706-C0EC-4FB1-ABA7-0118372F6900/testapp.app/PlugIns/NotificationWithAttachmentExtension.appex   
Dec 31 21:00:53 iPhone SpringBoard(PlugInKit)[51] <Notice>: plugin com.test.app.NotificationWithAttachmentExtension interrupted   
Dec 31 21:03:56 iPhone SpringBoard(PlugInKit)[51] <Notice>: Hub connection error Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.test.app.NotificationWithAttachmentExtension" UserInfo={NSDebugDescription=connection to service named com.test.app.NotificationWithAttachmentExtension}   
Jun 29 13:33:36 iPhone SpringBoard(libextension.dylib)[51] <Notice>: PlugInKit error in beginUsing:   
Jun 17 23:33:04 iPhone SpringBoard(libextension.dylib)[51] <Notice>: killing invalid plugIn   
Dec 31 21:00:00 iPhone SpringBoard(UserNotificationsServer)[51] <Error>: Extension error whilst trying to modify push notification F502-9B36: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.test.app.NotificationWithAttachmentExtension" UserInfo={NSDebugDescription=connection to service named com.test.app.NotificationWithAttachmentExtension}   
Dec 31 21:00:00 iPhone SpringBoard(UserNotificationsServer)[51] <Notice>: [com.test.app] Saving notification F502-9B36   
Dec 31 21:00:00 iPhone SpringBoard(libextension.dylib)[51] <Notice>: completed calling plugIn beginUsing: for pid: 0  

Соответствующее расширение.plist:

  <dict>
    <key>NSExtensionAttributes</key>
    <dict>
      <key>UNNotificationExtensionCategory</key>
      <string>attachmentCategory</string>
      <key>UNNotificationExtensionInitialContentSizeRatio</key>
      <real>1</real>
    </dict>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.usernotifications.service</string>
        <key>NSExtensionPrincipalClass</key>
        <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
  </dict>

Что не так или нет?

заранее спасибо

20 ответов

Решение

Наконец-то у меня все работает правильно, и это то, что я помню из этой проблемы.

1) Не используйте устройства с бета-версией iOS10, потому что одна из проблем, с которыми я столкнулся, заключалась в том, что я использовал бета-версию.

2) только приложение запрашивает права доступа APNS, это не требуется для использования в правах для расширения.

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

4) Атрибуты NSExtensionAttributes не требуются, просто используйте NSExtensionPointIdentifier и NSExtensionPrincipalClass для расширения.plist. Если вы не используете свой собственный макет

5) Это работает даже при использовании методов регистрации токенов iOS 9.

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

Я думаю, что это покрывает все проблемы, которые у меня были

Что также может сделать трюк, это проверить цель развертывания для расширения. Шахта была установлена ​​на 10.2 в то время как устройство, на котором я тестировал, использовало (все еще) 10.1

После изменения цели развертывания на 10.0 UNNotificationServiceExtension Экземпляр был назван отлично

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

После запуска приложения, содержащего расширение:

  1. Установите точку останова в расширении
  2. Выберите "Отладка / Присоединить к процессу" по PID или имени
  3. Введите имя цели расширения
  4. Запустить push-уведомление

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

Если вы используете Firebase, попробуйте изменить полезную нагрузку следующим образом:

{
   “aps” : {
      “category” : “SECRET”,
      “mutable_content” : true,
      “alert” : {
         “title” : “Secret Message!”,
         “body”  : “(Encrypted)”
     },
   },
   “ENCRYPTED_DATA” : “Salted__·öîQÊ$UDì_¶Ù∞è   Ω^¬%gq∞NÿÒQùw”
}

Поле mutable_content отображается в поле изменяемого содержимого в APN. Для более подробной информации перейдите по этой ссылке.

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

Итак, проверьте это:

  1. Нажмите на свой проект приложения слева.
  2. Нажмите на вашу основную цель приложения.
  3. Выберите General.
  4. В разделе "Встроенные двоичные файлы" убедитесь, что ваше расширение указано в списке, если нет, добавьте его.

Swift 5 Простой способ

 this is very easy way just do it like this

Похоже, что ваш plist смешивает 2 списка. В игре есть 2 расширения:

  1. Notification Content Extension - отвечает за отображение контента через контроллер представления
  2. Расширение службы уведомлений - отвечает за выборку контента в фоновом режиме перед отображением уведомления

Вот лист для Notification Content Extension цель:

введите описание изображения здесь

Вот лист для Notification Service Extension цель:

р

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

Для тех, кто хочет просто вызвать точку останова в расширении уведомлений вашего приложения, этот процесс довольно прост в Xcode 11.3:

  1. Выберите схему расширения (не схему родительского приложения).
  2. Выбрать Edit Scheme.
  3. Выберите исполняемый файл в качестве родительского приложения.
  4. Снимите отметку Debug executable. Снимая этот флажок, вы информируете Xcode о необходимости отладки расширения вместо родительского приложения. Это ключ к остановке Xcode в точках останова расширения.
  5. Выбрать Automatically под Launch вариант.
  6. Запустите схему расширения (не родительского приложения).
  7. Отправьте на устройство уведомление. Прибыль.

Если что-то другое не вызывает капризность Xcode, вышеуказанные настройки должны гарантировать, что всякий раз, когда вы выбираете и запускаете схему расширения, будут срабатывать точки останова внутри расширения. Вы можете вернуться и проверитьDebug executable на шаге 4, если вы хотите, чтобы Xcode останавливался на точках останова в родительском приложении.

Совет: не забудьте добавить "mutable-content": 1 в полезной нагрузке JSON уведомления, иначе вас ждет серьезная печаль (iOS не будет вызывать расширение без этого ключа).


Вот изображение моего диалогового окна редактора схем для расширения уведомлений:

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

Удаление фреймворка и таргетинг 10.2 позволили снова вызвать мое расширение.

Если вам интересно, какие рамки по какой-либо причине вы можете найти здесь: https://github.com/plu/JPSimulatorHacks

В моем случае это было то, что я забыл выбрать NotificationServiceExtension в схеме как конкретное приложение, а не "мое приложение", где я пытаюсь его использовать. Итак, я запускал "свое приложение" и ждал точек останова в коде другого приложения (NotificationServiceExtension), и поэтому они никогда не появлялись. Я пробовал все предложения до этого.

Моя проблема была в два раза. Первое, вероятно, было то, что я установил Info.plist свойство NSExtensionPrincipalClass для bundle.identifier.NotificationService вместо ProductModuleName.NotificationService, Имя модуля по умолчанию, но я ошибочно изменил идентификатор при отладке некоторых других вещей, связанных с разными схемами и разными целями.

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

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

После борьбы с этим я, наконец, сделал эту работу за себя, просто изменив 2 вещи.

  1. BundleID цели NotificationServiceExtension должен быть другим. Предпочтительный стиль com.companyname.appname.notificationservice(что угодно). Установка того же идентификатора пакета для приложения приводит к сбою сборки на устройстве.
  2. Главное - цель развертывания. Я дважды проверял это с помощью цели приложения, но мы также должны проверить цель развертывания только что созданной цели NotificationServiceExtenion, которая по умолчанию является последней версией. Установите минимальную версию iOS, которую вы хотели бы поддерживать, но выше, чем ios 10.

Примечание. Убедитесь, что у вас есть "mutable-content": 1 в удаленной полезной нагрузке.

Надеюсь, это кому-то поможет.

В настоящее время я работаю над Xcode 12.3 и Swift 5.2, и когда я отказался от основной цели проекта и цели расширения службы уведомлений с iOS 14.2 до iOS 13.2, это сработало!

Другая возможность - проверить название категории в plist-файле UNNotificationContentExtension.

Строковое значение "UNNotificationExtensionCategory" в plist и "category/click_action" полезной нагрузки должно совпадать.

public func didReceiveNotificationRequest(request: UNNotificationRequest, withContentHandler contentHandler: (UNNotificationContent) -> Void) метод в UNNotificationServiceExtension изменился между быстрыми версиями.

Некоторые из онлайн примеров не актуальны.

Убедитесь, что метод, который вы переопределяете в своем подклассе UNNotificationServiceExtension

Я имел:

func didReceive(request: UNNotificationRequest, withContentHandler contentHandler:(UNNotificationContent) -> Void)

который не работал, пока я не изменился на:

func didReceiveNotificationRequest(request: UNNotificationRequest, withContentHandler contentHandler: (UNNotificationContent) -> Void)

Убедитесь, что у вас установлен "None". Посмотрите на скриншот. С другими параметрами didReceive не работает

конфигурация

Спасибо за все хорошие предложения, которые помогли мне исправить мое несоответствие с целью развертывания и отсутствующим изменяемым контентом. Но у меня все еще были проблемы с вызовом NSE. Я нашел решение в исходном коде из этого блога, https://medium.com/gits-apps-insight/processing-notification-data-using-notification-service-extension-6a2b5ea2da17 . Мне не хватало Embed App Extensions , которые копировали расширение в мое приложение. Почему это отсутствовало, я не уверен, я не рассматривал это как обязательный шаг в различных руководствах, которые я читал.

Расширение приложения для встраивания - это просто "Фаза копирования файла", которая была переименована, как описано здесь /questions/57866366/kak-spravitsya-s-etapom-sborki-xcode-vstroit-rasshirenie-prilozheniya/61135812#61135812

Это руководство также очень помогло настроить различные идентификаторы приложений, группы приложений, профили и т. д.: https://blog.logrocket.com/implement-push-notifications-react-native-onesignal/

Система выполняет расширение приложения для содержимого уведомлений только в том случае, если полезная нагрузка удаленного уведомления содержит следующую информацию:

  • Полезная нагрузка должна включать mutable-content ключ со значением 1.

  • Полезные данные должны включать словарь предупреждений с заголовком, подзаголовком илиосновной информацией.

Указание полезной нагрузки удаленного уведомления:

{
   “aps” : {
      “category” : “SECRET”,
      “mutable-content” : 1,
      “alert” : {
         “title” : “Secret Message!”,
         “body”  : “(Encrypted)”
     },
   },
   “ENCRYPTED_DATA” : “Salted__·öîQÊ$UDì_¶Ù∞è   Ω^¬%gq∞NÿÒQùw”
}