I'm trying to make communication notifications work with the remote push notifications I have set up, specifically so that I can get user avatars to appear in the notification. I have successfully set up a Notification Service Extension for my app, which I've verified works (breakpoints hit in the NotificationService
class, and I'm able to modify the title), and by following guide, I end up with this code:
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent {
contentHandler(bestAttemptContent)
}
let personHandle = INPersonHandle(value: "senderID", type: .unknown)
let person = INPerson(
personHandle: personHandle,
nameComponents: .init(givenName: "senderName", familyName: "family name"),
displayName: "senderName",
image: nil,
contactIdentifier: nil,
customIdentifier: "some-unique-id"
)
let intent = INSendMessageIntent(
recipients: nil,
outgoingMessageType: .outgoingMessageText,
content: "some content",
speakableGroupName: nil,
conversationIdentifier: "unique-user-id-conv",
serviceName: nil,
sender: person,
attachments: nil
)
let interaction = INInteraction(intent: intent, response: nil)
interaction.direction = .incoming
interaction.donate(completion: nil)
do {
let updatedContent = try request.content.updating(from: intent)
let mutableBestAttemptContent = (updatedContent.mutableCopy() as? UNMutableNotificationContent)!
mutableBestAttemptContent.userInfo = request.content.userInfo
contentHandler(mutableBestAttemptContent)
} catch {
}
}
When I receive a notification, this code runs and I've verified with breakpoints that contentHandler(mutableBestAttemptContent)
is called and that the intent is donated without an error.
For now, I've omitted adding an image, as I want to first get a minimal example working where the name of the person
is displayed (though I have also tested this with a hardcoded INImage(url: validURL)
without success), but this code is not working.
Additionally, I have the following:
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsSupported</key>
<array>
<string>INSendMessageIntent</string>
</array>
</dict>
...
</dict>
</dict>
<dict>
<key>NSUserActivityTypes</key>
<array>
<string>INSendMessageIntent</string>
</array>
...
</dict>
I'm at a bit of a loss for why this is not working, and there's shockingly little documentation on this matter, so I'm not even sure how to approach debugging this. Anyone have any ideas?
It seems you accidentally left in some of the auto generated code in your source, so contentHandler
is always being called immediately. It should work if you remove the first block of code calling it
if let bestAttemptContent {
contentHandler(bestAttemptContent) // REMOVE this if statement
}