web-dev-qa-db-ja.com

プッシュ通知応答からデータを取得する方法Swift 3 / iOS

次のライブラリを使用してプッシュ通知を生成しています。

https://github.com/edamov/pushok

プッシュ通知は機能しましたが、Swift 3.で応答を抽出する方法がわかりません。

これが私が持っているものです。

// Push notification received
    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
        // Print notification payload data
        print("Push notification received: \(data)")

        let aps = data[AnyHashable("aps")]!

        print(aps)
    }

プッシュ通知を作成でき、コンソールメッセージは機能しますが、これを出力します...

Push notification received: [AnyHashable("samplekey"): samplevalue, AnyHashable("aps"): {
    alert =     {
        body = hey;
        title = "Hello!";
    };
    sound = default;
}]
{
    alert =     {
        body = hey;
        title = "Hello!";
    };
    sound = default;
}

だから私の質問は、「body」と「title」のアラート内のデータにどのようにアクセスするのですか?

変数にアクセスしようとしましたが、どのようにアクセスするべきかわからず、チュートリアルでこの件に関するドキュメントが見つからなかったため、エラーが発生し続けます。

6
Joseph Astrahan

これはジョセフが見つけた方法を行うためのより安全な方法だと思います。

guard
    let aps = data[AnyHashable("aps")] as? NSDictionary,
    let alert = aps["alert"] as? NSDictionary,
    let body = alert["body"] as? String,
    let title = alert["title"] as? String
    else {
        // handle any error here
        return
    }

print("Title: \(title) \nBody:\(body)")
22
ffabri

強制アンラップの使用を回避する方法を見つけてみてください。次の場合:

 let alert = aps["alert"]! as! NSDictionary
 let body = alert["body"] as! String
 let title = alert["title"] as! String

上記の値のいずれかが欠落している場合、アプリケーションはクラッシュします。

代わりに、まず通知モデルを紹介しましょう。

class MTNotification {
    let alert: [String: AnyHashable]
    var title: String?
    var body: String?

    init(alert: [String: AnyHashable]) {
        self.alert = alert
    }
}

何かを使用して、未加工の通知データの処理中に発生する可能性のあるエラーを追跡します。 Errorプロトコルに準拠させる方が良いでしょう。

enum MTError: Error {
    // Observe your transformation and extend error cases
    case missingProperty(id: String)
}

ヘルパークラスを使用して、アプリデリゲートを汚染しないようにします。この場合、データの通知への変換を処理できます。

class MTNotificationBuilder {

     /// Build a notification from raw data
     ///
     /// - Parameter data: Classic notification payload, received from app delegate
     /// - Returns: customized MTNotification
     /// - Throws: error while building a valid MTNotification object
    static func build(from data: [AnyHashable : Any]) throws -> MTNotification {
        guard let aps = data["aps"] as? [String: AnyHashable] else {
            // Do some error handlig
            throw MTError.missingProperty(id: "aps")
        }

        guard let alert = aps["alert"] as? [String: AnyHashable] else {
            // Do some error handlig
            throw MTError.missingProperty(id: "aps")
        }

        let notification = MTNotification(alert: alert)
        // Assign values read as optionals from alert dictionary
        notification.title = alert["title"] as? String
        notification.body = alert["body"] as? String

        return notification
    } 
}

最後に行う必要があるのは、ビルダー関数を呼び出して結果を確認することだけです。厳密で、どのような場合でもエラーが発生する可能性があります。また、使用すると、後で保守しやすくなります。

func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {

    do {
        let notification = try MTNotificationBuilder.build(from: data)
        print(notification.alert)
    } catch let error {
        print(error)
    }
}
3
dirtydanee

プロジェクトの「機能」でバックグラウンドモードを「オン」にし、「リモート通知」をオンにしたことを確認してください。 AppDelegateクラスに以下のメソッドを追加します。このメソッドは、通知の提示時に呼び出されます。

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print(notification.request.content.userInfo)
        completionHandler([ .alert,.badge, .sound])

}
2
Pranit

さて、私は答えを見つけました。以下のようにします。

let aps = data[AnyHashable("aps")]! as! NSDictionary        
let alert = aps["alert"]! as! NSDictionary
let body = alert["body"] as! String
let title = alert["title"] as! String

誰かがより安全な答えを持っているならば、私はこれを編集するか、それを投稿してくれるとありがたいです。

2
Joseph Astrahan