🛎️

【iOS / Swift】PUSH通知を通知センターに表示する前に、PUSH通知の内容を更新してから表示する方法

2024/08/26に公開

PUSH通知を通知センターに表示する前に、PUSH通知の内容を更新してから表示する方法

概要

Notification Service Extensionの使用方法をまとめました。

きっかけ

アプリにて、PUSH通知ペイロードのbodyテキストを更新してから通知センターに表示して欲しい、という要望がありました。
また、アプリがフォアグラウンド・バックグラウンド・未起動時全てで本文更新処理をして欲しいとのことだったので調査・実装しました。

Notification Service Extension

PUSH通知のペイロードを更新して通知センターに表示するためにはNotification Service Extensionを使用する必要があります。
まずはプロジェクトにNotification Service Extensionを追加します。

  1. File > New > Targetを選択します。

  2. Notification Service Extensionを選択します。

  3. Product NameにNotificationServiceと入力してFinishをクリックする

以上の操作で、Notification Service Extensionがプロジェクトに追加されました。
(Target追加となるため、プロジェクトによってはNotification Service Extension用の証明書の作成が必要になります。)

注意点

Notification Service Extensionを起動するには、通知ペイロードにaps.mutable-content属性を指定する必要があります。

/// サンプル
{
  "aps": {
    "alert": {
      "title": "Title",
      "body": "Body"
    },
    "mutable-content": 1 // mutable-content属性を1に指定
  }
}

実装

先ほどNotificationServiceを追加したことにより、プロジェクトにNotificationService.swiftというファイルが作成されます。
NotificationServiceUNNotificationServiceExtensionを継承しており、下記メソッドが用意されています。

  • didReceive(_:, withContentHandler:):PUSH通知が端末に届いたタイミングで呼ばれます。
  • serviceExtensionTimeWillExpire:上の didReceive(_:withContentHandler:) の処理がタイムアウト(30秒)した場合に呼ばれます。

ペイロードのbodyを更新する

didReceiveメソッドでペイロードのbodyを取り出し・更新します。
今回は「;(セミコロン)」に対して「\n(改行コード)」に変換する処理を行っています。

// PUSH通知が届いた時に呼び出される
override func didReceive(_ request: UNNotificationRequest,
  withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
  self.contentHandler = contentHandler
  bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

  if let bestAttemptContent: UNMutableNotificationContent = bestAttemptContent {
  // 現在の本文を取得する
  var modifiedBody: String = bestAttemptContent.body

  // 置換処理を実行
  modifiedBody = modifiedBody.replacingOccurrences(of: ";", with: "\n")

  // 修正した本文をセット
  bestAttemptContent.body = modifiedBody
  contentHandler(bestAttemptContent)
  }
}

こちらを実装後にPUSH通知を送信してみると、アプリのフォアグラウンド・バックグラウンド・未起動時にPUSH通知に表示されるテキストが変換されているはずです。

さいごに

今回はbody(本文)に対して変換処理をかけていますが、title(タイトル)に対しても可能です。

以下NotificationService.swfitのソースコードになります。

import UserNotifications

// PUSH通知内容の変更を行うエクステエンション
class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    // PUSH通知が届いた時に呼び出される
    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent: UNMutableNotificationContent = bestAttemptContent {
            // 現在の本文を取得する
            var modifiedBody: String = bestAttemptContent.body
            
            // 置換処理を実行
            modifiedBody = modifiedBody.replacingOccurrences(of: ";", with: "\n")
            
            // 修正した本文をセット
            bestAttemptContent.body = modifiedBody
            contentHandler(bestAttemptContent)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        if let contentHandler: ((UNNotificationContent) -> Void) = contentHandler,
           let bestAttemptContent: UNMutableNotificationContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

Discussion