Cordova PushPlugin:Can';找不到变量:onNotificationAPN

Cordova PushPlugin:Can';找不到变量:onNotificationAPN,cordova,push-notification,apple-push-notifications,Cordova,Push Notification,Apple Push Notifications,我正在用Cordova/Phonegap构建一个iOS应用程序,它使用推送通知 我正在使用在客户端应用程序中实现通知 我已经设置了APNS端,当我在应用程序暂停或关闭时发送通知时,通知会正确显示。但是,当我在应用程序中时,插件会抛出一个错误: Can't find variable: onNotificationAPN 当我查看Xcode输出时,我看到通知实际上已传递: 2014-03-02 23:12:58.746 EASP 2014[5792:60b] Notification recei

我正在用Cordova/Phonegap构建一个iOS应用程序,它使用推送通知

我正在使用在客户端应用程序中实现通知

我已经设置了APNS端,当我在应用程序暂停或关闭时发送通知时,通知会正确显示。但是,当我在应用程序中时,插件会抛出一个错误:

Can't find variable: onNotificationAPN
当我查看Xcode输出时,我看到通知实际上已传递:

2014-03-02 23:12:58.746 EASP 2014[5792:60b] Notification received
2014-03-02 23:12:58.747 EASP 2014[5792:60b] Msg: {"alert":"testing...",foreground:"1"}
然而,在应用程序中什么也没发生,我被onNotificationAPN错误卡住了

我已经尝试了所有的方法来调试这个,但是我被卡住了。知道为什么会这样吗

下面是我用来设置通知的代码:

  // SET UP PUSH NOTIFICATIONS
  var pushNotification;
  pushNotification = window.plugins.pushNotification;

  if ( device.platform == 'android' || device.platform == 'Android' ) {
    pushNotification.register(
      successHandler,
      errorHandler, {
        "senderID":"<xxxxx>",
        "ecb":"onNotificationGCM"
      }
    );
  }
  else {
    pushNotification.register(
      tokenHandler,
      errorHandler, {
        "badge":"false",
        "sound":"false",
        "alert":"true",
        "ecb":"onNotificationAPN"
      }
    );
  }

  // result contains any message sent from the plugin call
  function successHandler (result) {
    console.log('result = ' + result);
    navigator.notification.alert(
      result,
      onConfirm,
      'Title of app',
      'Dismiss'
    );
  }

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

  function tokenHandler (result) {

    var uuid = device.uuid;
    var platform = device.platform;
    console.log(platform);
    if (platform == 'iOS'){
      var os = 'ios';
    } else {
      var os = 'android';
    }
    hash = result+'<title of app>';
    hash = md5(hash);
    var xmlHttp = null;

    xmlHttp = new XMLHttpRequest();

    var url = 'https://<notification server>/?token='+result+'&id='+uuid+'&hash='+hash+'&os='+os;

    xmlHttp.open( "GET", url, false );

    xmlHttp.send( null );
    console.log(xmlHttp.responseText);
    return xmlHttp.responseText;
  }

  // iOS
  function onNotificationAPN (event) {
    console.log(event);
    if ( event.alert ) {
      navigator.notification.alert(event.alert);
      //alert(event.alert);
    }

    if ( event.sound ) {
        var snd = new Media(event.sound);
        snd.play();
    }

    if ( event.badge ) {
      pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
    }

  }

  function receivedEvent(id) {
    navigator.notification.alert(
      id,
      onConfirm,
      '<title of app>',
      'Dismiss'
    );
  }

  function onConfirm(buttonIndex,id) {
  }
//设置推送通知
通知;
pushNotification=window.plugins.pushNotification;
if(device.platform==“android”| | device.platform==“android”){
pushNotification.register(
成功者,
错误处理程序{
“senderID”:“senderID”,
“ecb”:“通知GCM”
}
);
}
否则{
pushNotification.register(
令牌处理程序,
错误处理程序{
“徽章”:“假”,
“声音”:“假”,
“警报”:“正确”,
“欧洲央行”:“通知”
}
);
}
//结果包含从插件调用发送的任何消息
函数successHandler(结果){
log('result='+result);
navigator.notification.alert(
结果,,
onConfirm,
“应用程序标题”,
“解雇”
);
}
//结果包含插件调用返回的任何错误描述文本
函数errorHandler(错误){
log('error='+error);
}
函数标记处理程序(结果){
var uuid=device.uuid;
var platform=device.platform;
控制台日志(平台);
如果(平台==“iOS”){
var os='ios';
}否则{
var os='android';
}
散列=结果+“”;
hash=md5(hash);
var xmlHttp=null;
xmlHttp=新的XMLHttpRequest();
var url='https://?token='+result+'&id='+uuid+'&hash='+hash+'&os='+os;
open(“GET”,url,false);
xmlHttp.send(空);
log(xmlHttp.responseText);
返回xmlHttp.responseText;
}
//iOS
函数onNotificationAPN(事件){
console.log(事件);
如果(event.alert){
navigator.notification.alert(event.alert);
//警报(event.alert);
}
if(event.sound){
var snd=新媒体(事件声音);
snd.play();
}
如果(event.badge){
pushNotification.setApplicationBadgeNumber(successHandler、errorHandler、event.badge);
}
}
函数receivedEvent(id){
navigator.notification.alert(
身份证件
onConfirm,
'',
“解雇”
);
}
函数onConfirm(按钮索引,id){
}

在进一步挖掘之后,它终于开始工作了

下面是代码:

  // SET UP PUSH NOTIFICATIONS
  var addCallback = function addCallback(key, callback) {
    if (window.pushCallbacks === undefined) {
        window.pushCallbacks = {}
    }
    window.pushCallbacks[key] = callback;
  };


  var pushNotification;
  pushNotification = window.plugins.pushNotification;

  if ( device.platform == 'android' || device.platform == 'Android' ) {
    pushNotification.register(
      successHandler,
      errorHandler, {
        "senderID":"<xxxxx>",
        "ecb":"onNotificationGCM"
      }
    );
  }
  else {
    pushNotification.register(
      tokenHandler,
      errorHandler, {
        "badge":"true",
        "sound":"true",
        "alert":"true",
        "ecb":"pushCallbacks.onNotificationAPN"
      }
    );
  }

  // result contains any message sent from the plugin call
  function successHandler (result) {
    console.log('result = ' + result);
    navigator.notification.alert(
      result,
      onConfirm,
      '<title of app>',
      'Dismiss'
    );
  }

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

  function tokenHandler (result) {

    var uuid = device.uuid;
    var platform = device.platform;
    console.log(platform);
    if (platform == 'iOS'){
      var os = 'ios';
    } else {
      var os = 'android';
    }
    hash = result+'<title of app>';
    hash = md5(hash);
    var xmlHttp = null;

    xmlHttp = new XMLHttpRequest();

    var url = '<title of app>/?token='+result+'&id='+uuid+'&hash='+hash+'&os='+os;
    console.log('URL IS: '+url);

    xmlHttp.open( "GET", url, false );

    xmlHttp.send( null );
    console.log(xmlHttp.responseText);
    addCallback('onNotificationAPN', onNotificationAPN);
    return xmlHttp.responseText;

  }

  // iOS
  function onNotificationAPN (event) {
    if ( event.alert ) {
      navigator.notification.alert(event.alert);
    }

    if ( event.sound ) {
        var snd = new Media(event.sound);
        snd.play();
    }

    if ( event.badge ) {
      pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
    }

  }

  function receivedEvent(id) {
    navigator.notification.alert(
      id,
      onConfirm,
      '<title of app>',
      'Dismiss'
    );
  }

  function onConfirm(buttonIndex,id) {
  }
开始时,以及

"ecb":"pushCallbacks.onNotificationAPN"
注册iOS推送通知时


现在可以工作了。

我也遇到了同样的问题,最后通过在窗口上显式注册onnotificatianpan函数解决了这个问题:

var onNotificationAPN = function(event) {
    console.log(event);
    if ( event.alert ) {
      navigator.notification.alert(event.alert);
      //alert(event.alert);
    }

    if ( event.sound ) {
        var snd = new Media(event.sound);
        snd.play();
    }

    if ( event.badge ) {
      pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);
    }

  }

if(typeof window.onNotificationAPN === 'undefined'){
    window.onNotificationAPN = onNotificationAPN;
}

我也有同样的问题。该示例基本上描述了全局范围内的函数。我把我的放在设置事件侦听器的函数范围内,所以找不到它

(function () {
    document.addEventListener('deviceready', onDeviceReady.bind(this), false);

    function onDeviceReady() {
        // registration happened in here, as a string
        pushNotification.register(,, {...  , "ecb":"onNotificationAPN"});

    }

    function onNotificationAPN(e) {
        // handle notification
    }

})();
我的解决方案是将onNotificationAPN()移到函数外部,使其成为全局函数。它是作为字符串传递的,而不是作为函数指针/闭包传递的

(function () {
    document.addEventListener('deviceready', onDeviceReady.bind(this), false);

    function onDeviceReady() {
        // registration happened in here
    }

})();

function onNotificationAPN(e) {
    // handle notification
}

onNotificationAPN必须向窗口公开。为了清楚起见,您能解释一下为什么这样做有效吗?这也为我解决了这个问题,但我不知道为什么。因为回调在cordova包装器中使用时超出了范围,所以它们需要发布到窗口范围才能可见
(function () {
    document.addEventListener('deviceready', onDeviceReady.bind(this), false);

    function onDeviceReady() {
        // registration happened in here
    }

})();

function onNotificationAPN(e) {
    // handle notification
}