iOS10 UNNotificationServiceExtension not called

2019-03-12 22:20发布

问题:

Im implementing new iOS10 extension to use rich notifications. Im trying to test it on push notifications but is not working, I just receive a simple notification and is not going through the extension.

I did all that it's specified in the official sites and some other places:

  • I have my app up and running with push notifications and the right provisioning profile
  • I added a new target to my app, a Notification Service Extension
  • Implemented my own code (it doesn't matter really because is not even entering to the new class)
  • Also I had to set a provisioning profile for this extension, I just use one with a wildcard, I don't see any documentation specifying if the extension target has to enable push notifications capability, in that case I would need a specific provisioning for this one, at the moment I just use a wildcard prov, anyway it matches (it must match) the profile I use in the app target, and push notifications capability is enabled for the app target only.
  • I added UNNotificationExtensionCategory and NSExtensionPointIdentifier. Also Im sending the category as part of the push payload from the server.

As I said, I get the notification but never goes through the extension. I see how the OS tries to load the extension but then throws an error with no relevant description to identify the problem:

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  

Relevant extension .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>

What's wrong or missing?

Thanks in advance

回答1:

What also might do the trick is check your deployment target for the extension. Mine was set at 10.2 while the device I was testing on was (still) using 10.1

After altering the deployment target to 10.0 the UNNotificationServiceExtension instance was called perfectly



回答2:

And if you've done everything correctly, don't forget to attach it to the proces.

After running the app that contains the extension:

  1. Set your breakpoint in the extension
  2. Select Debug / Attach to Process by PID or name
  3. Enter the name of the extension target
  4. Trigger the push notification


回答3:

Finally I have this working correctly, and this is what I remember from this issue.

1) Do not use devices with iOS10 beta version, because one of the problems I had was because I was using a beta version.

2) only the app requres APNS entitlements, this is not required for the privisoning used for the extension.

3) I was using a provisioning profile matching the id of the extension (not wildcard), anyway I cannot confirm if it works fine or not with wildcard.

4) NSExtensionAttributes are not required, just use NSExtensionPointIdentifier and NSExtensionPrincipalClass for the extension .plist. Unless you are using your own layout

5) This is working even using iOS 9 token registration methods.

6) don't forget mutable-content value in the payload coming in the push notification, this is the only mandatory value you need from the server to go through the extension.

I think this covers all the problems I had



回答4:

Came here the second time. The first time, this answer helped me, the second time, it didn't. After a lot of (internal) swearing I found out that I had somehow accidentally removed the extension from Embedded Binaries in my main app target. When I added the extension back, my extension would be called again.

So check this:

  1. Click on your app project to the left.
  2. Click on your main app target.
  3. Choose General.
  4. Under Embedded Binaries, make sure your extension is listed, if not, add it.


回答5:

It seems like your plist is mixing 2 plists. There are 2 extensions in play:

  1. Notification Content Extension - responsible for displaying the content via a view controller
  2. Notification Service Extension - responsible for fetching content in the background before notification is displayed

Here is the plist for Notification Content Extension target:

Here is the plist for Notification Service Extension target:



回答6:

If you are using Firebase, then try changing the payload as:

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

The mutable_content field maps to the mutable-content field on APNs. For more details, go through this link.



回答7:

The public func didReceiveNotificationRequest(request: UNNotificationRequest, withContentHandler contentHandler: (UNNotificationContent) -> Void) method in UNNotificationServiceExtension has changed between swift versions.

Some of the online examples are not up to date.

Make sure the method you're overriding in your custom subclass of UNNotificationServiceExtension

I had:

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

which didn't work until i changed to:

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



回答8:

Be sure that you have 'None' configuration set. Look at the screenshot. With other parameters didReceive doesn't work.

Configuration



回答9:

After trying many of the possible fixes already given without success, it dawned on me that a framework had been mistakenly added to our extension target rather than the unit test target.

Removing the framework and targeting 10.2 allowed my extension to be called once again.

If you are curious as to which framework for whatever reason you can find it here: https://github.com/plu/JPSimulatorHacks



回答10:

My issue was two fold. The first probably was that I had set the Info.plist property NSExtensionPrincipalClass to bundle.identifier.NotificationService instead of ProductModuleName.NotificationService. Module name is the default, but I had erroneously changed to the identifier when debugging some other things related to different schemes and different targets.

The second issue was that I tested by running the notification service target. For me it worked much better when running the app target. I saw some other people recommending to use the notification service target to enable debugging. But that works fine when running the app target as well. You'll have to attach the debugger to your notification service manually though.

The way I discovered the above was to create a new test project with minimal code. In hindsight I definitely recommend that approach instead of trying out all the different solutions found on stackoverflow etc