Require.js with Phonegap and Push Notification for

2019-03-02 09:49发布

问题:

Im building an app with Phonegap, Backbone.js and Require.js. The app implements Phonegap Push Notification. At the moment, the loading of the scripts in index.html looks like this:

<script type="text/javascript" src="cordova.js"></script> 
<script type="text/javascript" charset="utf-8" src="PushNotification.js"></script>

<script type="text/javascript" src="js/app/index.js"></script>
<script type="text/javascript">
    app.initialize();
</script>

<script data-main="js/app" src="js/require.js"></script>

index.js looks like this:

var app = {
// Application Constructor
initialize: function() {
    this.bindEvents();
},


// Bind Event Listeners
bindEvents: function() {

    document.addEventListener('deviceready', this.onDeviceReady, false);
},


onDeviceReady: function() {

    var pushNotification = window.plugins.pushNotification;
    pushNotification.register(app.tokenHandler,app.errorHandler,{"badge":"true","sound":"true","alert":"true","ecb":"app.onNotificationAPN"});

},


errorHandler:function(error) { 
    //alert('in errorHandler');
    //alert(error);
},

/*
 * 
 * For iOS
 */        
tokenHandler:function(status) {

    //save the status to server

},


onNotificationAPN: function(event) {

//display alert

},

};

In tokenHandler, I want to call a model I have defined as a Require.js module. So, I integrated index.js with Require.js. Index.html became this:

<script type="text/javascript" src="cordova.js"></script> 
<script type="text/javascript" charset="utf-8" src="PushNotification.js"></script>

<script data-main="js/app" src="js/require.js"></script>

The index.js file now looks like this:

define(function (require) {

var app = {
    // Application Constructor
    initialize: function() {
    this.bindEvents();
    },


    // Bind Event Listeners
    bindEvents: function() {

    document.addEventListener('deviceready', this.onDeviceReady, false);
    },


    onDeviceReady: function() {

    var pushNotification = window.plugins.pushNotification;
    pushNotification.register(app.tokenHandler,app.errorHandler,{"badge":"true","sound":"true","alert":"true","ecb":"app.onNotificationAPN"});

    },


    errorHandler:function(error) { 
    //alert('in errorHandler');
    //alert(error);
    },

    /*
     * 
     * For iOS
     */        
    tokenHandler:function(status) {

        //save the status to server

    },


    onNotificationAPN: function(event) {

    //display alert

    },

};

return app;
});

The in app.js, I do:

... ... ...

require(['jquery', 'backbone', 'app/router', 'app/index'], function ($, Backbone, Router, Index) {

var router = new Router();
Index.initialize();

Backbone.history.start();

});

The problem occurs in the callback to pushNotification.register(), which is app.onNotificationAPN. With the loading of the index.js as a Require module, this leads to an error:

processMessage failed: Error

When i user an anonymous function in place of the call to app.onNotificationAPN, I also get the same error.

What should the correct callback be?

回答1:

I had similar problems, just that my onNotificationAPN didn't get called. I used this guide as a reference (to setting up the register-call) - Push Notifications guide

Try using the guides way to add the callback function. You can also have a look at my push notification handler as a requirejs module. It works fine :) Btw, I'm using Durandal with knockout for building my app.

In my index.html I have a reference to PushNotification.js and that file is also in my project.

Index.html:

<body>
 <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
 <script type="text/javascript" src="Scripts/jquery/jquery-2.0.3.min.js"></script>
 <!-- PhoneGap plugins -->
 <script type="text/javascript" charset="utf-8" src="Scripts/phoneGap/PushNotification.js"></script>
....
<script type="text/javascript" src="Scripts/require.js"></script>
<script>
   var useragent = navigator.userAgent.toLowerCase();
 if (useragent.match(/android/) || useragent.match(/iphone/) || useragent.match(/ipad/) || useragent.match('ios')) {
document.addEventListener('deviceready', onDeviceReady, false);
    }
    else {
        onDeviceReady();
    }

    function onDeviceReady() {
        ....

        require.config({
            baseUrl: 'App',
            paths: {
                "main": "main"
            }
        });
        require(["main"]);
    };
</script>

And the push notification module:

define([
'knockout'
], function (
ko
) {
var pushNotification = window.plugins.pushNotification;

function addCallback(key, callback) {
    if (window.callbacks === undefined) {
        window.callbacks = {};
    }
    window.callbacks[key] = callback;
};

function registerDevice() {
    pushNotification.register(
    tokenHandler,
    errorHandler, {
        "badge": "true",
        "sound": "false",
        "alert": "true",
        "ecb": "callbacks.notificationHandler"
    });
};

// result contains any message sent from the plugin call
function successHandler(result) {
    alert('result = ' + result);
};

// result contains any error description text returned from the plugin call
function errorHandler(error) {
    alert('error = ' + error);
};

function tokenHandler(result) {
    // Your iOS push server needs to know the token before it can push to this device
    // here is where you might want to send it the token for later use.
    console.log('post token to rikardo', result);

    svc.post('Notification', ko.toJSON({ DeviceToken: result }));
    addCallback('notificationHandler', onNotificationAPN);
};

// iOS
function onNotificationAPN(event) {
    var model = {},
        type = event.type;

    if (event.inAppMessage)
        model = JSON.parse(event.inAppMessage);

    if (type == 'AchievementViewModel') {
        pushModalHandler.addItem(model);
        pushModalHandler.displayModals('achievement');
    }

    if (type == 'TimeQuestViewModel') {
        pushModalHandler.addItem(model);
        pushModalHandler.displayModals('timeQuest');
    }
};

return {
    registerDevice: registerDevice
};
});

I hope this helps!