Help us understand the problem. What is going on with this article?

【Swift】いまさらですがiOS10でプッシュ通知を実装したサンプルアプリを作ってみた

iOS10のプッシュ通知はこんな感じ

iOS10のプッシュ通知は、今までとはデザインが違いますね。
コードもSwift3になったので、違います。
Swift3が出てきてからもうかなり時間が経ってしましましたが…きっと、これから実装される方もいるはず!
ぜひご参考にしていただけるかと思います。

295.png

サンプル

動作環境と事前準備

推奨動作環境

  • Mac OS Sierra 10.12 以上
  • Xcode8 以上
  • iPhone iOS 10 以上

事前準備

サンプルプロジェクト一覧

すべて自由に使ってOKです▼

言語 プッシュ通知 リッチプッシュ ペイロード取得
Swift SwiftPushApp SwiftRichPushApp SwiftPaylpadApp
  • 上記3つのサンプルを用意しました
    • 通常のプッシュ通知のみ実装した、SwiftPushApp
    • SwiftPushAppに加えて、プッシュ通知を開くとWebViewを表示できるリッチプッシュ機能を実装した、SwiftRichPushApp
    • SwiftPushAppに加えて、配信したプッシュ通知からメッセージなどのデータを取得するペイロード機能を実装した、SwiftPayloadApp
  • 使い方は各リンク先のREADMEにしたがってください◎
  • それぞれについて次でコード解説します('▼'*♪

コード紹介

そもそもプッシュ通知の仕組みって?

iOSの場合はAPNsというApple社のプッシュ通知用サーバーを介してプッシュ通知は配信されます。
下図のように①~⑤の流れでプッシュ通知は端末に届きます。

095.png

この中で「②デバイストークン発行」でAPNsから発行されたデバイストークンを端末で取得し、サーバー側に保存する処理は、アプリ側に実装する必要があります。

<プッシュ通知の基本>デバイストークンの取得とサーバーへの登録

AppDelegate
import UIKit
import UserNotifications
import NCMB

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    // APIキーの設定
    let applicationkey = "YOUR_NCMB_APPLICATIONKEY"
    let clientkey      = "YOUR_NCMB_CLIENTKEY"

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // SDKの初期化
        NCMB.setApplicationKey(applicationkey, clientKey: clientkey)

        // デバイストークンの要求
        if #available(iOS 10.0, *){
            /** iOS10以上 **/
            let center = UNUserNotificationCenter.current()
            center.requestAuthorization(options: [.alert, .badge, .sound]) {granted, error in
                if error != nil {
                    // エラー時の処理
                    return
                }
                if granted {
                    // デバイストークンの要求
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        } else {
            /** iOS8以上iOS10未満 **/
            //通知のタイプを設定したsettingを用意
            let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            //通知のタイプを設定
            application.registerUserNotificationSettings(setting)
            //DevoceTokenを要求
            UIApplication.shared.registerForRemoteNotifications()
        }

        // MARK: アプリが起動されるときに実行される処理を追記する場所


        return true
    }

    // デバイストークンが取得されたら呼び出されるメソッド
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // 端末情報を扱うNCMBInstallationのインスタンスを作成
        let installation : NCMBInstallation = NCMBInstallation.current()
        // デバイストークンの設定
        installation.setDeviceTokenFrom(deviceToken)
        // 端末情報をデータストアに登録
        installation.saveInBackground {error in
            if error != nil {
                // 端末情報の登録に失敗した時の処理                
            } else {
                // 端末情報の登録に成功した時の処理
            }
        }
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // MARK: アプリが起動しているときに実行される処理を追記する場所

    }
}

リッチプッシュの処理

リッチプッシュって何?

  • プッシュ通知にURLを載せて配信し、プッシュ通知開封時にWebビューで表示することができる機能です

001.png

  • 実装は簡単で、上記デバイストークン処理のコードに加え、コメント(// MARK:)の2箇所(処理を実行するタイミング)にそれぞれに下記のコードを追記するだけです◎
リッチプッシュを表示させる処理
// MARK: アプリが起動されるときに実行される処理を追記する場所
if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as! [AnyHashable : Any]! {
    // リッチプッシュを表示させる処理
    NCMBPush.handleRichPush(userInfo)
}

// MARK: アプリが起動しているときに実行される処理を追記する場所
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    // リッチプッシュを表示させる処理
    NCMBPush.handleRichPush(userInfo)
}

ペイロードの処理

ペイロードって何?

  • プッシュ通知にJSONデータを持たせて配信し、開封時にプッシュ通知からデータを取得することができる機能です
  • ペイロードとして取得したデータは、アプリ内で使用することが可能です

Payload.png

  • リッチプッシュと同様に、コメント(// MARK:)の2箇所(処理を実行するタイミング)にそれぞれに下記のコードを追加することでデータを取得可能です
    • サンプルアプリではその表示までを実装しています!
ペイロードからデータを取得する処理
// MARK: アプリが起動されるときに実行される処理を追記する場所
if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as! [AnyHashable : Any]! {
    // ペイロードからデータを取得する処理
    let key: Array! = Array(userInfo .allKeys)
    let value: Array! = Array(userInfo .allValues)

    if key != nil && value != nil {
        for i in 0..<key.count {
            let key0 = key[i] as! String
            payloadKeyData.append(key0)
            let value0 = String(describing: value[i])
            payloadValueData.append(value0)
        }

    }    
}

// MARK: アプリが起動しているときに実行される処理を追記する場所
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    // ペイロードからデータを取得する処理
    let key: Array! = Array(userInfo.keys)
    if key != nil {
        for i in 0..<key.count {
            let key0 = key[i] as! String
            let value0 = userInfo["\(key0)"]
            payloadKeyData.append(key0)

            if let unwrapValue = value0 {
                if key0 == "aps" {
                    let apsUnwrapValue = String(describing: unwrapValue)
                    payloadValueData.append(apsUnwrapValue)
                } else {
                    payloadValueData.append(unwrapValue as! String)
                }
            }
        }
    }
}

※ただし、上記の例では、フィールドに取得したデータの格納用配列を準備します

AppDelegate.swift
// payload
var payloadKeyData: Array<String> = []
var payloadValueData: Array<String> = []

参考

GitHubにたくさんサンプルアプリを公開しています!
https://github.com/natsumo/

natsumo
ニフクラ mobile backend の使い方をまとめています。
https://github.com/natsumo/
fjct
クラウド・IoT 関連サービスを開発・提供している企業です。(こちらは、富士通クラウドテクノロジーズの有志にて運営しております。)
https://fjct.fujitsu.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした