サーバー構築不要!スマートフォンアプリ向けの新クラウド

トップ >ドキュメント >プッシュ通知(Swift):基本的な使い方

プッシュ通知(Swift)

基本的な使い方

概要

このページでは、プッシュ通知の基本的な使い方について説明していきます。

設定の流れ

ニフクラ mobile backendのプッシュ通知機能は、
Appleが提供しているApple Push Notification Service(以下、APNs)
と連携することで、通知の配信を行っています。
Swiftアプリでプッシュ通知を受信するまでの設定は以下のような流れとなっています。

  1. APNsの設定と証明書の取得
  2. ニフクラ mobile backendでの設定
  3. アプリでの設定

APNsの設定とニフクラ mobile backendへの設定

まずはじめに、Appleの開発者サイトでAPNsを有効にして、
ニフクラ mobile backendと連携させるための証明書を取得する必要があります。
以下のドキュメントを参考に、 p12証明書、p8認証キーどちらかの方法で
Appleの開発者サイトでの設定とニフクラ mobile backendへの設定を行ってください。

アプリでの設定

アプリ側では、端末をニフクラ mobile backendに登録する処理を
実装していきます。

なお、ニフクラ mobile backendのSwift SDKは
インストールと初期化が済んでいるものとして説明しますので、
未実施の場合はクイックスタートをご覧ください。

Xcodeでの対応

※Life Cycleを Swift UI Appで使用する場合はこちらの基本的な使い方(Swift UI App版)をご覧ください

TARGETS -> 「Signing & Capabilities」を選択し、「+ Capability」をクリックします。
Push Notifications を検索し、ダブルクリックして追加します。

再度「+ Capability」をクリックして、 Background Modesを検索し、ダブルクリックして追加します。
Remote notifications機能をチェックを入れて、有効にしてください。

正常に追加されましたら、Signing情報の下に Push Notifications と Background Modesが表示されます。

capabilities

次にBundleIDとプロビジョニングファイルを設定します。

  1. Signing & Capabilities画面 でBundle Identifierを入力します。

  2. Provisioning ProfileのところでImport Profileのボタンを押してプロビジョニングファイルをインポートします。

Signing

配信端末情報の登録

APNsでは、プッシュ通知の配信端末を一意に識別するDevice Tokenを利用し、
各端末への配信を行っています。

そのため、APNsからDevice Tokenを取得したあとで、
データストアに配信端末情報として登録する必要があります。
AppDelegateファイル内のapplication:didFinishLaunchingWithOptionsメソッド内で
Device Tokenの要求をAPNsに対して行います。

・サンプルコード
Frameworkのimportが必要となります。

import UserNotifications
///////////////////////////途中省略///////////////////////////////
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
    if((error) != nil) {
        return
    }
    if granted {
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}

Device Tokenが取得できた場合は、同じAppDelegate.swiftの
application:didRegisterForRemoteNotificationsWithDeviceTokenメソッド
が呼び出されますので、端末情報をデータストアに登録します。

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    //端末情報を扱うNCMBInstallationのインスタンスを作成
    let installation : NCMBInstallation = NCMBInstallation.currentInstallation

    //Device Tokenを設定
    installation.setDeviceTokenFromData(data: deviceToken)

    //端末情報をデータストアに登録
    installation.saveInBackground(callback: { result in
        switch result {
        case .success:
            //端末情報の登録が成功した場合の処理
            print("保存に成功しました")
        case let .failure(error):
            //端末情報の登録が失敗した場合の処理
            print("保存に失敗しました: \(error)")
            return;
        }
    })
}

端末情報はデータストアのinstallationクラスに保存されます。

installationクラスのフィールド

installationクラスには、通常クラスでデフォルトで生成されるフィールドとは別に、端末を特定するための様々な情報が保存されます。保存されるフィールドはiOS/Android,ご利用するSDKによって違いますが、主なフィールドについて、以下の表を参照してください。

※通常クラスでデフォルトで生成される主なフィールドについてはこちらをご確認ください。
※他に端末情報の任意フィールドを指定し、保存する方法はこちらをご確認ください。

フィールド名 フィールド説明
deviceToken 端末ごとにAPNs/FCMに割り振られたデバイストークンが格納されるフィールド。
deviceType 端末のOS情報(iosもしくはandroid)が格納されるフィールド。
appVersion 端末にインストールされているアプリバージョンが格納されるフィールド。iOSの場合 ビルドバージョンであるCFBundleVersion(Xcode上のCurrent Project Versionで設定する値)が格納される。
applicationName 端末にインストールされているアプリ名が格納されるフィールド。iOSの場合、CFBundleNameが格納される。
sdkVersion 端末にインストールされているアプリに用いられたsdkバージョンが格納されるフィールド。
timeZone 端末のタイムゾーンが格納されるフィールド。

以上でアプリ側での設定は完了です。
アプリをiOS端末で実行し、端末情報がデータストアに登録されるか確認してください。

アプリの再インストール時を考慮する場合

アプリが再インストールされた場合などに、前回のインストール時に保存された端末情報が
mobile backend上に残ったままの場合が考えられます。
その場合には端末情報の登録でdeviceTokenの重複エラーが発生するため、
エラーが発生したときの処理を実装する必要があります。

端末情報でエラーが発生した場合にエラーコードを取得し、
409001(重複してはいけない値を登録しようとした場合に発生するエラーコード)かを判定し、
データストアに保存されている端末情報を上書きするようにします。

let installation : NCMBInstallation = NCMBInstallation.currentInstallation
installation.setDeviceTokenFromData(data: deviceToken)
installation.saveInBackground(callback: { result in
    switch result {
    case .success:
        //端末情報の登録が成功した場合の処理
        break
    case let .failure(error):
        //端末情報の登録が失敗した場合の処理
        let errorCode = (error as! NCMBApiError).errorCode;
        if (errorCode == NCMBApiErrorCode.duplication) {
            //失敗した原因がdeviceTokenの重複だった場合
            self.updateExistInstallation(installation: installation)
        } else {
            //deviceTokenの重複以外のエラーが返ってきた場合
        }
        return
    }
})

端末情報を上書き保存するupdateExistInstallation:は以下のようにします。

//deviceTokenの重複で端末情報の登録に失敗した場合に上書き処理を行う
func updateExistInstallation(installation: NCMBInstallation) -> Void {
var installationQuery : NCMBQuery<NCMBInstallation> = NCMBInstallation.query
installationQuery.where(field: "deviceToken", equalTo: installation.deviceToken!)
installationQuery.findInBackground(callback: {results in
    switch results {
    case let .success(data):
        //上書き保存する
        let searchDevice:NCMBInstallation = data.first!
        installation.objectId = searchDevice.objectId
        installation.saveInBackground(callback: { result in
            switch result {
            case .success:
                //端末情報更新に成功したときの処理
                break
            case .failure:
                //端末情報更新に失敗したときの処理
                break
            }
        })
    case .failure:
        //端末情報検索に失敗した場合の処理
        break
    }
})

installationが削除された時を考慮する場合

以下の例のように、何らかの理由により有効な installation が削除されてしまった場合、通常の実装では installation の再登録は行われず、該当の端末へはプッシュ通知を配信することができなくなってしまいます。

  • 管理者の操作ミスによる削除
    • コントロールパネル上の操作ミスなど
  • 管理者が意図しない操作による削除

そのため、 installation を再度登録するには、以下の処理を追加実装する必要があります。

let installation : NCMBInstallation = NCMBInstallation.currentInstallation
installation.setDeviceTokenFromData(data: deviceToken)
installation.saveInBackground(callback: { result in
    switch result {
    case .success:
        //端末情報の登録が成功した場合の処理
        break
    case let .failure(error):
        //端末情報の登録が失敗した場合の処理
        let errorCode = (error as! NCMBApiError).errorCode;
        if (errorCode == NCMBApiErrorCode.noDataAvailable) {
            //失敗した原因がdeviceTokenの該当データが無い場合
            self.reRegistInstallation(installation: installation)
        } else {
            //deviceTokenの該当データが無いエラー以外が返ってきた場合
        }
        return
    }
})

installation が削除された場合(端末情報の該当データがmoble backend 上に存在しない場合)は、以下のように installation を再作成します。

//mobile backend上に該当データがない場合に新規作成処理を行う
func reRegistInstallation(installation: NCMBInstallation) -> Void {
    //objectIdのみ削除し、installationが再生成されるようにする
    installation.objectId = nil
    //端末情報をデータストアに登録
    installation.saveInBackground(callback: { result in
        switch result {
        case .success:
            //端末情報の登録が成功した場合の処理
            break
        case let .failure(error):
            //端末情報の登録が失敗した場合の処理
            break
        }
    })
}

プッシュ通知をアプリから送信する

管理画面だけでなく、アプリからも他の端末へプッシュ通知を送信することができます。

プッシュ通知の設定を行う

iOS端末へのプッシュ通知を行う場合は、バッジの増加フラグや、着信音の設定などが可能です。
content-availableとバッジ数増加フラグは、どちらかしか設定できません。
(参考)REST APIリファレンス:プッシュ通知登録

// プッシュ通知オブジェクトの作成
let push : NCMBPush = NCMBPush()
push.sound = "default" //音楽ファイル(iOS端末のみ設定可能)設定
push.badgeIncrementFlag = true //バッジ数増加フラグ(iOS端末のみ設定可能)設定
push.contentAvailable = false //content-available(iOS端末のみ設定可能)設定
push.message = "プッシュ通知です" //メッセージの設定
push.isSendToIOS = true //iOS端末を送信対象に設定する
push.setImmediateDelivery() // 即時配信

// プッシュ通知を配信登録する
push.sendInBackground(callback: { result in
    switch result {
    case .success:
        print("登録に成功しました。プッシュID: \(push.objectId!)")
    case let .failure(error):
        print("登録に失敗しました: \(error)")
        return;
    }
})

Android端末へのプッシュ通知を行う場合は、起動画面、ダイアログプッシュ通知の有効フラグを設定できます。

// プッシュ通知オブジェクトの作成
let push : NCMBPush = NCMBPush()
// メッセージの設定
push.message = "プッシュ通知です" //メッセージの設定
push.action = "ReceiveActivity" //アクションの設定
push.title = "testPush" //タイトルの設定
push.isSendToAndroid = true//Android端末を送信対象に設定する
push.setImmediateDelivery() //即時配信

// プッシュ通知を配信登録する
push.sendInBackground(callback: { result in
    switch result {
    case .success:
        print("登録に成功しました。プッシュID: \(push.objectId!)")
    case let .failure(error):
        print("登録に失敗しました: \(error)")
        return;
    }
})

プッシュ通知のスケジューリング

プッシュ通知の配信時刻を指定することができます。
配信時刻を指定するか、即時配信を指定しないと、プッシュ通知を登録することができません。
(参考)REST APIリファレンス:プッシュ通知登録

// プッシュ通知オブジェクトの作成
let push : NCMBPush = NCMBPush()

push.message = "プッシュ通知です"// メッセージの設定
push.isSendToIOS = true //iOS端末を送信対象に設定する
push.isSendToAndroid = true //Android端末を送信対象に設定する
// 配信時刻を設定する
let formatter : DateFormatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
formatter.timeZone = TimeZone(secondsFromGMT: 0)
push.deliveryTime = formatter.date(from: "2020-07-24T10:10:01.964Z")

// プッシュ通知を配信登録する
push.sendInBackground(callback: { result in
    switch result {
        case .success:
            print("登録に成功しました。プッシュID: \(push.objectId!)")
        case let .failure(error):
            print("登録に失敗しました: \(error)")
            return;
    }
})

管理画面からプッシュ通知を配信する

ここからは、管理画面からプッシュ通知を配信する方法を説明します。

プッシュ通知を送信する

管理画面左側メニューのプッシュ通知をクリックし、プッシュ通知の画面を開きます。

新しいプッシュ通知ボタンをクリックすると、プッシュ通知作成画面が表示されます。
このページで新たなプッシュ通知を作成できます。タイトル、メッセージ、JSONデータを記入してください。
※プッシュ通知の設定でメッセージを入力しなかった場合は、端末にプッシュ通知が表示されません。
(上記の場合でも、プッシュ通知の受信音の設定、JSONデータの取得は可能です。)
※iOS宛プッシュ通知の設定は、iOS8未満は合計256バイトまで、iOS8以降は合計2Kバイトまでがサポート対象となります。
新規プッシュ通知作成

配信日時の指定を行います。以下の例では、作成されたプッシュ通知が即時に配信される設定になっています。

プッシュ通知送信日時を指定する場合は、配信日時の欄で日時を選択し、希望する日時を指定してください。

配信期限の指定では電源が切れているなどの事情により通知を受け取れなかった端末への再送信期間を設定できます。デフォルトの設定では再送信できる期間が10日間となっていますが1~28日間、1~24時間の間で、期間を指定できます。

また、配信期限を日時で指定する場合は、日時の指定画面が表示されます。

次に、配信を行うプラットフォームを選択してください。AndroidとiOSの両方にプッシュ通知を送信することも可能です。
Androidを選択した場合は、以下のようにアクション設定と、ダイアログ表示の設定画面が表示されます。
Android独自設定

iOSを選択した場合は、以下のようなiOS端末へのプッシュ通知を行うための設定画面が開きます。
※「バッジ件数」が「インクリメントする」に設定されている場合はInstallationクラスbadgeフィールドの値に対してインクリメントを実行し、プッシュ通知のパラメータに付加して送信しています。
※「音声ファイル名」が設定されている場合でも、プッシュ通知を受信した際にアプリがフォアグラウンド状態だと通知音が鳴りません。
※設定した「音声ファイル名」が存在しない場合は、デフォルトの通知音が鳴ります。
iOS独自設定

絞り込みを行いたい場合には、配信端末を「installationクラスから絞り込み」とし、条件を設定してください。
絞り込み配信設定

最後に「プッシュ通知を作成する」ボタンをクリックすると、プッシュ通知が作成されます。

テンプレートを使用する

プッシュ通知作成画面上部にあるテンプレート機能では、プッシュ通知作成時に入力・設定した内容を保存しておくことができます。
毎回同一内容のプッシュ通知を作成している場合、テンプレート機能を使用することで、プッシュ作成時の手間を省くことができます。

タイトルやメッセージを入力した後、「テンプレートとして保存する」ボタンをクリックしてください。
プッシュテンプレート保存ボタン
すると、以下のようなポップアップが表示されます。
プッシュテンプレート保存
テンプレート名を入力し、「保存する」ボタンをクリックすると、テンプレートとして保存されます。

保存されたテンプレートはプルダウンから選択可能です。
プッシュテンプレート選択時

  • 注意
    • 1アプリにつき20テンプレートの保存が可能です。
    • 配信日時、配信期限、パーミッションの内容は、テンプレートとして保存されません。

プッシュ通知の詳細画面について

配信後は、プッシュ通知の詳細画面よりプッシュ通知ID・実際の配信数・配信エラー内容などの情報を確認することが可能です。

プッシュ通知の配信結果

プッシュ通知の配信ステータスについて

プッシュ通知一覧の画面では、プッシュ通知のタイトルの右側に、配信ステータスが表示されます。

こちらのステータスが「未配信」、「配信済み」、「配信中」以外だった場合、プッシュ通知の配信が失敗した端末が存在しています。
配信ステータスの詳細は こちらの「プッシュ通知のステータスについて」項目にてご参考ください。
※以下の画像では、「配信済み(一部エラー)」と表示されている部分がステータスに該当します。

プッシュステータス

配信ステータスが「配信済み(一部エラー)」の場合は、該当のプッシュ通知をクリックすると表示される、画面右側のプッシュ通知詳細画面最下部の「配信エラー内容」にエラーの詳細が出力されていますので、ご確認ください。

また、配信ステータスが「配信エラー」になる場合の主な理由と対策は、以下の通りです。

  • iOS証明書の不具合
    • iOS証明書を再設定し、端末情報を再度登録したうえで、プッシュ通知をテストしてください。
    • iOS証明書の有効期限が切れている場合は、証明書を更新してください。※iOS証明書の有効期限切れについては、こちらもご参考ください。
  • iOS証明書またはAndroidプッシュ通知設定ファイルを設定していないのに、両方のOSを対象にしてプッシュ通知を登録
    • 配信対象はデフォルトでiOS/Androidの両方なので、iOS証明書とAndroidプッシュ通知設定ファイルをどちらも設定していないとエラーになります。

配信エラーとなった場合に、管理画面からmobile backend側のログについて
確認することはできませんので、ご不明な点がございましたらお気軽にお問い合わせください。

ダミーデータを登録した端末を指定してプッシュ通知を行わない

プッシュ通知を配信する端末の中に、
テスト目的などでダミーデータを入力した端末が含まれていると、
他の端末も含めてプッシュ通知が配信されない場合がございます。
アプリ側でプッシュ通知が受信されるかを確認する場合は、
ダミーデータを含んだ端末を配信対象に含めないでください。

過去のプッシュ通知データについて

プッシュ通知配信履歴自動バックアップ機能によってバックアップされたデータは、「過去のプッシュ通知データ一覧」画面にてダウンロード/削除が可能です。

過去のプッシュ通知データ

過去のプッシュ通知データ一覧

プッシュ通知配信履歴自動バックアップ機能

バックアップ機能概要

プッシュ通知の配信に伴い、配信済みのプッシュ通知オブジェクトは内部データベースに累積いたします。
こちらはプッシュ通知の登録ごとに作成されますので、個通のプッシュ通知を多用されるなど、プッシュ通知登録数が多い場合につきましては、オブジェクトの容量肥大が考えられます。
容量が肥大しますと、プッシュ通知の配信パフォーマンス低下やストレージ容量の逼迫に繋がります。
上記現象を防ぐため、プッシュ通知オブジェクトが約100万件(※)を超過した場合、超過分の配信済みのプッシュ通知オブジェクト(開封数データ含む)は自動でバックアップされます。
※レコード件数ではなく、データサイズ(非公開情報)での制限を設けているため、約100万件の制限と表記しております。

  • バックアップデータ(CSV)は管理画面よりダウンロード/削除が可能です。
  • バックアップデータは、プッシュ通知データの場合は配信時刻(JST)の年月ごとにファイルが分けられ、 push_YYYYMM.csv という形式のファイル名となります。開封数データの場合は登録日時(JST)の年月ごとにファイルが分けられ、 push_open_state_YYYYMM.csv という形式のファイル名となります。例としてプッシュ通知の配信時刻が 2022年3月15日09:00(JST)だった場合、そのデータは push_202203.csv というファイル名のファイルに出力されます。
  • 開封数データとは、あるプッシュ通知に対してある1時間の間にAndroid、iOSそれぞれの端末から何件のプッシュ通知開封登録があったかどうかを1レコードに保存しているデータのことです。管理画面での開封率の確認にて使われていたデータとなっています。プッシュ通知の時間毎の開封数ではなく、合計開封数については、開封数集計データエクスポート機能よりエクスポートいただけます。
  • バックアップデータは、API経由でのアクセスは行えません。 (該当プッシュ通知データへのアクセスもしくは開封通知登録を行った場合、E404001エラーが返却されます)

以上より、配信済みのプッシュ通知オブジェクトへAPIアクセスする処理を組み込まれる場合は、自動バックアップによりエラーが発生する可能性があることを考慮した実装をお願いいたします。

過去のプッシュ通知データに関する注意事項
  • バックアップデータの容量も、ストレージ容量にカウントされます。
  • バックアップデータはエクスポート機能のエクスポート対象外です。
  • バックアップデータ内のデータには、APIアクセスできません。
  • 自動バックアップは内部で随時行われています(実施タイミングについては非公開)ので、以下の点にご注意ください。
    • 自動バックアップが行われている際に削除されたプッシュ通知データについては、バックアップデータ(CSV)に存在する可能性がございます。何卒ご了承ください。
    • 一度ダウンロードされたバックアップデータであっても、中身が更新されていることがございます。削除する際には必ず最新版のバックアップデータをダウンロードしておくことを推奨いたします。一度削除してしまったバックアップデータの復元は不可能ですので、ご注意ください。(有償での復元対応も致しかねます。)

プッシュ通知でJSONデータを取得する

タイトルやメッセージ以外にもプッシュ通知が保持するデータ(ペイロード)をプッシュ通知の受信時に取得することが可能です。

また、JSON形式で任意のデータ(カスタムペイロード)を付加してプッシュ通知を配信し、取得することも可能です。

アプリの状態によって処理を行うメソッドが異なっており、ペイロードを取得するためのキーも名前が異なります。

※iOS 13.6以降で、アプリがバックグラウンドにいる状態でペイロードを取得するには、配信登録でcontent-availableをtrueに指定する必要があります。
なお、content-availableがfalseでも、フォアグラウンド状態では取得可能です。

アプリが起動されたときにプッシュ通知の情報(ペイロード)からデータを取得する

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

    // SDKの初期化や device token を取得する処理

    // プッシュ通知の情報(ペイロード)からデータを取得する
    if let payload = launchOptions?[.remoteNotification] as? [String: AnyObject] {
        let payloadText = payload.map{
            (key, value) in "\(key): \(value)"
        }.joined(separator: "\n")
        print(payloadText)
    }
    return true
}

アプリの起動中に配信されたプッシュ通知の情報(ペイロード)からデータを取得する

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    // プッシュ通知の情報(ペイロード)からデータを取得する
    let payloadText = userInfo.map{
        (key, value) in "\(key): \(value)"
    }.joined(separator: "\n")
    print(payloadText)   
}

ペイロードの取得にはRemote Notification機能の有効化が必要です。
TARGETS -> 「Signing & Capabilities」を選択し、「+ Capability」をクリックします。
Capability 画面から Background Modesを検索し、ダブルクリックして追加します。
Remote notifications機能をチェックを入れて、有効にしてください。

Remote_notification

ペイロードの内容について

iOS端末へのプッシュ通知では、以下のペイロードが受信されます。

パラメータ名 説明 データ型
com.nifcloud.mbaas.PushId プッシュ通知ID 16文字の文字列
com.nifcloud.mbaas.RichUrl リッチプッシュ通知用URL 文字列
aps プッシュ通知の設定(別表) オブジェクト
- ユーザー設定値 オブジェクト

apsには通知音やバッジ数についての設定が含まれています。

パラメータ名 説明 データ型
sound プッシュ通知音のファイル名 文字列
alert タイトル、メッセージ オブジェクト
category アクション用のカテゴリ名 文字列
badge バッジ数 数値
content-available バックグラウンド通知フラグ 1

※ iOS 13.6 以降ではbadge数を取得することができるのは、content-availableがfalseかつアプリがフォアグラウンド状態の時のみです(badge数とcontent-availableは同時に設定ができないため)

JSONデータのパラメータに使用可能な文字の制限

JSONデータのパラメータには、以下の文字が使用できません。

  1. ダブルクォーテーション「"」
  2. ドット「.」
  3. 先頭にドル記号「$」

お探しの内容が見つからなかった場合はユーザーコミュニティ もご活用ください。(回答保証はいたしかねます)
なお、 Expertプラン以上のお客様はテクニカルサポートにてご質問を承らせて頂きます。

推奨画面サイズ1024×768px以上

ページの先頭へ