Phonegap IOS - Plugin Push Setup

2019-01-29 12:37发布

问题:

I'm developing an App using Phonegap and Phonegap Build. The app has been pretty much completed but I'm not working on the Push Notifications.

I'm struggling to get a device to even be registered at all. I've added the following plugin to my project (added in the config for phonegap build) https://github.com/phonegap/phonegap-plugin-push

I added the plugin and have following in my javascript file.

var app = {
    // Application Constructor
    initialize: function () {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function () {
        document.addEventListener('deviceready', this.onDeviceReady, false);

    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function () {
        app.receivedEvent('deviceready');

        var push = PushNotification.init({
            "android": {
                "senderID": "1234567890"
            },
            "ios": { "alert": "true", "badge": "true", "sound": "true" },
            "windows": {}
        });

        push.on('registration', function (data) {
            console.log("registration event");
            //document.getElementById("regId").innerHTML = data.registrationId;
            alert(data.registrationId)
            console.log(JSON.stringify(data));
        });

        push.on('notification', function (data) {
            console.log("notification event");
            console.log(JSON.stringify(data));
            var cards = document.getElementById("cards");
            var card = '<div class="row">' +
                  '<div class="col s12 m6">' +
                  '  <div class="card darken-1">' +
                  '    <div class="card-content black-text">' +
                  '      <span class="card-title black-text">' + data.title + '</span>' +
                  '      <p>' + data.message + '</p>' +
                  '    </div>' +
                  '  </div>' +
                  ' </div>' +
                  '</div>';
            cards.innerHTML += card;

            push.finish(function () {
                console.log('finish successfully called');
            });
        });

        push.on('error', function (e) {
            console.log("push error");
        });

    },
    // Update DOM on a Received Event
    receivedEvent: function (id) {
        var parentElement = document.getElementById(id);
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');

        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');

        console.log('Received Event: ' + id);
    }
};

function successHandler(result) {
    alert('result = ' + result); //Here you will get your device id.
}


function errorHandler(error) {
    alert('error = ' + error);
}

So, I'm not sure where to go from here exactly. I've set up an account with push wizard and have created the additional certificates, but that is not picking up any devices as I assume there is no devices that are set to receive notifications yet.

So I guess my main issue is, am I missing something stupid like a registration stage, where my device is registered to receive notifications?

回答1:

You are not using the this context correctly. This is a common mistake. The Javascript this does NOT work like the Java this.

The reason it does not work is because the this gets resolved at run-time, not assemble-time (or compile-time). When the event fires, this resolves to the the global this because your app object is now out of scope. The event fires *outside* of your app object.

A quick fix would be to do app.onDeviceReady instead of this.onDeviceReady You can test this by making youronDeviceReady() a global function and leaving the this in place.

These videos should help. – Best of Luck.

  • Context in JavaScript - 1/4 - Purpose and Problems with JavaScript's "This"

  • Context in JavaScript - 2/4 - How JavaScript Decides What "This" Actually Is

  • Context in JavaScript - 3/4 - "This" May Not Be What You Expected & How to Fix It

  • Context in JavaScript - 4/4 - Mastering "This:" Additional Techniques & Future Support



回答2:

So there was 2 sections to this, First what jesseMonroy mentioned, my code wasn't being picked up properly and my js file wasn't being run properly.

The second part was that I wasn't calling a register function, which allows you to get a device_token.

        push.registerDevice({ alert: true, badge: true, sound: true }, function (status) {
            app.myLog.value += JSON.stringify(['registerDevice status: ', status]) + "\n";
            app.storeToken(status.deviceToken);
            alert(status.deviceToken)
        });

This is what i was missing. my whole init section looks like this;

var push = PushNotification.init({
            "android": {
                "senderID": "1234567890"
            },
            "ios": { "alert": "true", "badge": "true", "sound": "true" },
            "windows": {}
        });

        push.on('registration', function (data) {
            console.log("registration event");
            //document.getElementById("regId").innerHTML = data.registrationId;
            alert(data.registrationId)
            console.log(JSON.stringify(data));
        });

        push.on('notification', function (data) {
            console.log("notification event");
            console.log(JSON.stringify(data));
            var cards = document.getElementById("cards");
            var card = '<div class="row">' +
                  '<div class="col s12 m6">' +
                  '  <div class="card darken-1">' +
                  '    <div class="card-content black-text">' +
                  '      <span class="card-title black-text">' + data.title + '</span>' +
                  '      <p>' + data.message + '</p>' +
                  '    </div>' +
                  '  </div>' +
                  ' </div>' +
                  '</div>';
            cards.innerHTML += card;

            push.finish(function () {
                console.log('finish successfully called');
            });
        });

        push.on('error', function (e) {
            console.log("push error");
        });


        //  var pushNotification = window.plugins.PushNotification;
        push.registerDevice({ alert: true, badge: true, sound: true }, function (status) {
            app.myLog.value += JSON.stringify(['registerDevice status: ', status]) + "\n";
            app.storeToken(status.deviceToken);
            alert(status.deviceToken)
        });