"Modify the payload of a remote notification before it’s displayed on the user’s iOS device."
사용자의 iOS 기기에서 원격 노티피케이션이 표시되기 전에 원격 노티피케이션의 페이로드를 수정합니다.
아래와 같은 사항이 필요한 경우 사용자의 iOS 기기에서 원격 노티피케이션의 컨텐트를 수정하길 원할 수 있습니다.
원격 노티피케이션 수정은 iOS 앱 번들 내부에 포함시켜야 하는 노티피케이션 서비스 앱 확장이 필요합니다. 앱 확장은 시스템이 사용자에게 컨텐츠를 표시하기 전에 원격 노티피케이션의 컨텐츠를 받음으로써 노티피케이션 페이로드를 업데이트할 시간을 확보할 수 있습니다. 확장이 처리할 노티피케이션을 어떤 것으로 할지 제어할 수 있습니다.
Important
노티피케이션 서비스 앱 확장은 사용자에게 알림을 표시하기 위한 시스템에서 설정된 원격 노티피케이션에서만 작동합니다. 알림이 앱에서 사용될 수 없거나 페이로드가 소리 재생 혹은 아이콘 badge만 구체화하고 있다면, 앱 확장은 사용되지 않습니다.
노티피케이션 서비스 앱 확장은 iOS 앱 내부에 별도의 번들로 제공됩니다. 이 확장을 앱에 추가하려면 아래처럼 수행해야 합니다.
Xcode에서 제공하는 노티피케이션 서비스 앱 확장 템플릿은 기본값 구현을 포함합니다. 이는 수정할 수 있습니다.
UNMutableNotificationContent
객체를 생성하기 위해 didReceive(_:withContentHandler:)
메소드를 사용할 수 있습니다.serviceExtensionTimeWillExpire()
메소드를 사용할 수 있습니다.didReceive(_:withContentHandler:)
메소드는 페이로드 수정 및 제공된 컴플리션 핸들러 호출을 위한 시간으로 30초만을 갖습니다. 그보다 더 긴 시간을 요구하는 코드의 경우 시스템은 시스템에게 즉시 반환할 수 있는 것 무엇이든 반환되는 시점에 serviceExtensionTimeWillExpire()
메소드를 호출합니다. 어떤 메소드에서라도 컴플리션 핸들러 호출이 실패하는 경우 시스템은 노티피케이션의 기존 컨텐츠를 표시합니다.
Listing 1은 원격 노티피케이션을 사용해서 전달된 비밀 메시지의 컨텐츠를 암호해제하는 UNNotificationServiceExtension
객체의 구현을 보여주고 있습니다. didReceive(_:withContentHandler:)
메소드는 데이터를 암호해제하고, 성공적인 경우 수정된 버전의 노티피케이션 컨텐트를 반환합니다. 실패하거나 시간이 만료되는 경우 확장은 데이터가 아직 암호화되어 있다는 것을 나타내는 컨텐트를 반환합니다.
Listing 1 Decrypting data contained in a remote notification
// Storage for the completion handler and content.
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
// Modify the payload contents.
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler:
@escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy()
as? UNMutableNotificationContent)
// Try to decode the encrypted message data.
let encryptedData = bestAttemptContent?.userInfo["ENCRYPTED_DATA"]
if let bestAttemptContent = bestAttemptContent {
if let data = encryptedData as? String {
let decryptedMessage = self.decrypt(data: data)
bestAttemptContent.body = decryptedMessage
}
else {
bestAttemptContent.body = "(Encrypted)"
}
// Always call the completion handler when done.
contentHandler(bestAttemptContent)
}
}
// Return something before time expires.
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
// Mark the message as still encrypted.
bestAttemptContent.subtitle = "(Encrypted)"
bestAttemptContent.body = ""
contentHandler(bestAttemptContent)
}
}
시스템은 원격 노티피케이션의 페이로드가 아래 정보를 포함하고 있을 때에만 노티피케이션 서비스 앱 확장을 실행합니다.
Listing 2은 암호화된 데이터를 포함하고 있는 노티피케이션 페이로드에 대한 JSON 데이터를 보여주고 있습니다. 수정 가능한 컨텐트 플래그가 설정되어 있기 때문에 사용자의 기기는 상응하는 서비스 앱 확장을 알 수 있습니다.
Listing 2 Specifying the remote notification payload
{
"aps" : {
"category" : "SECRET",
"mutable-content" : 1,
"alert" : {
"title" : "Secret Message!",
"body" : "(Encrypted)"
},
},
"ENCRYPTED_DATA" : "Salted__·öîQÊ$UDì_¶Ù∞èΩ^¬%gq∞NÿÒQùw"
}
사용자에게 컨텐트가 전달되기 전에 원격 노티피케이션의 컨텐트를 수정하는 객체입니다.
https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension
https://velog.io/@panther222128/UNNotificationServiceExtension