cordova pushplugin 无法在 iOS 中获取设备令牌

Posted

技术标签:

【中文标题】cordova pushplugin 无法在 iOS 中获取设备令牌【英文标题】:cordova pushplugin can't get device token in iOS 【发布时间】:2015-08-24 21:23:42 【问题描述】:

我正在尝试使用 pushplugin https://github.com/phonegap-build/PushPlugin 在 cordova/phonegap 应用程序上添加推送通知

我用

安装了插件
cordova plugin add https://github.com/phonegap-build/PushPlugin.git

它似乎正在工作,因为当我第一次在我的设备(iPhone 5)上运行该应用程序时,它说“你的应用程序想要向你发送通知 bla bla ...”但是我没有得到设备令牌:它现在应该会显示警报。

这就是我编辑cordova创建的默认index.js的方式:

var pushNotification;
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 pushNotification;
		
		
		
		$("#app-status-ul").append('<li>deviceready event received</li>');
                
				document.addEventListener("backbutton", function(e)
				
                	$("#app-status-ul").append('<li>backbutton event received</li>');
  					
      				if( $("#home").length > 0)
					
						// call this to get a new token each time. don't call it to reuse existing token.
						//pushNotification.unregister(successHandler, errorHandler);
						e.preventDefault();
						navigator.app.exitApp();
					
					else
					
						navigator.app.backHistory();
					
				, false);
			
				try 
				 
                	pushNotification = window.plugins.pushNotification;
		      $("#app-status-ul").append('<li>registering ' + device.platform + '</li>');
                	if (device.platform == 'android' || device.platform == 'Android' ||
                            device.platform == 'amazon-fireos' ) 
			pushNotification.register(successHandler, errorHandler, "senderID":"661780372179","ecb":"onNotification");		// required!
					 else 
                    	pushNotification.register(tokenHandler, errorHandler, "badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN");	// required!
                	
                
				catch(err) 
				 
					txt="There was an error on this page.\n\n"; 
					txt+="Error description: " + err.message + "\n\n"; 
					alert(txt); 
				
		
		
		
		
		
		
		
		







// handle APNS notifications for ios
            function onNotificationAPN(e) 
                if (e.alert) 
                     $("#app-status-ul").append('<li>push-notification: ' + e.alert + '</li>');
                     // showing an alert also requires the org.apache.cordova.dialogs plugin
                     navigator.notification.alert(e.alert);
                
                    
                if (e.sound) 
                    // playing a sound also requires the org.apache.cordova.media plugin
                    var snd = new Media(e.sound);
                    snd.play();
                
                
                if (e.badge) 
                    pushNotification.setApplicationIconBadgeNumber(successHandler, e.badge);
                
            
            
            // handle GCM notifications for Android
            function onNotification(e) 
                $("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');
                
                switch( e.event )
                
                    case 'registered':
					if ( e.regid.length > 0 )
					
						$("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");
						// Your GCM push server needs to know the regID before it can push to this device
						// here is where you might want to send it the regID for later use.
						console.log("regID = " + e.regid);
					
                    break;
                    
                    case 'message':
                    	// if this flag is set, this notification happened while we were in the foreground.
                    	// you might want to play a sound to get the user's attention, throw up a dialog, etc.
                    	if (e.foreground)
                    	
							$("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');
						      
						        // on Android soundname is outside the payload. 
					                // On Amazon FireOS all custom attributes are contained within payload
					                var soundfile = e.soundname || e.payload.sound;
					                // if the notification contains a soundname, play it.
					                // playing a sound also requires the org.apache.cordova.media plugin
					                var my_media = new Media("/android_asset/www/"+ soundfile);

							my_media.play();
						
						else
							// otherwise we were launched because the user touched a notification in the notification tray.
							if (e.coldstart)
								$("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');
							else
							$("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');
						
							
						$("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');
                        //android only
						$("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');
                        //amazon-fireos only
                        $("#app-status-ul").append('<li>MESSAGE -> TIMESTAMP: ' + e.payload.timeStamp + '</li>');
                    break;
                    
                    case 'error':
						$("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');
                    break;
                    
                    default:
						$("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');
                    break;
                
            
            
            function tokenHandler (result) 
                $("#app-status-ul").append('<li>token: '+ result +'</li>');
                // 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.
				alert(result);
            
			
            function successHandler (result) 
                $("#app-status-ul").append('<li>success:'+ result +'</li>');
            
            
            function errorHandler (error) 
                $("#app-status-ul").append('<li>error:'+ error +'</li>');
            
            
			document.addEventListener('deviceready', onDeviceReady, true);
			
			
			
			
			
			
			
			
			
			
			
			
			
		
		
		
		
		
		
		
    ,
    // 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);
    
;

app.initialize();

在 index.html 中我没有做任何更改...只是像示例中一样添加了最后两个 .js 文件,即使 index.html 几乎是空的

<!DOCTYPE html>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<html>
    <head>
        <!--
        Customize this policy to fit your own app's needs. For more guidance, see:
            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
        Some notes:
            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
                * Enable inline JS: add 'unsafe-inline' to default-src
        -->
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>
    </head>
    <body>
    <script type="text/javascript">
            // var pushNotification;
			
			
			
			
			
	</script>
        <div class="app">
            <h1>Apache Cordova</h1>
            
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript" charset="utf-8" src="js/jquery_1.5.2.min.js"></script>
        <script type="text/javascript" src="js/PushNotification.js"></script>
    </body>
</html>

我什至不确定我是否在正确的位置添加了 var pushNotification 和所有函数... 我对 phonegap 很陌生,正在努力学习,但我发现的所有示例都与我制作新应用时创建的文件大不相同。

我还读到 pushplugin 和 iOS 8 存在一些问题,不知道这些问题是否已解决。 谁能给我任何建议?

谢谢

【问题讨论】:

【参考方案1】:

您的index.js 一切正常,您需要修复您的index.html 中的以下内容:

1:您不必自己包含PushNotifications.js,因此请删除&lt;script type="text/javascript" src="js/PushNotification.js"&gt;&lt;/script&gt;cordova.js 将自动包含所有插件 js 文件。

2:在index.js上方包含脚本jquery

3:在 index.js 中有以下代码

if (device.platform == 'android' || device.platform == 'Android' ||
                            device.platform == 'amazon-fireos' ) 

这会给你错误,因为device对象没有定义,实际上它是从设备插件导出的对象,所以通过runnig命令安装这个plugincordova plugin add cordova-plugin-device

4:在你的 index.html 中添加&lt;ul id="app-status-ul"&gt;&lt;/ul&gt;,这样你就可以看到结果了。 进行这些更改,您的代码将完美运行。

【讨论】:

非常感谢您的回复。是的,我已经添加了设备插件,忘了说。删除了 index.html 中的 PushNotification.js。我的大错误是我忘记在 errorHandler 函数中添加警报。完成后,我注意到配置文件有问题:Xcode 加载了通用配置文件,而不是 AdHoc 与我的证书。现在更改它显示设备令牌。 注意到 Xcode 会针对 iOS 8 和 iOS 7 版本的 pushplugin.m 中的大量已弃用对象发出警报。为此,我认为我将不得不像我在此处的一些帖子中看到的那样更新文件。当我在我的 iphone 上运行该应用程序时,它运行正常,但在 Xcode 上我收到此消息“进程启动失败:等待应用程序启动超时”并停止运行,即使在设备上应用程序仍在运行。如果您也对这些问题有任何想法,我接受建议。 不确定但尝试cordova plugin add cordova-plugin-push-notification 而不是从 git url 安装。对于 android,它修复了构建问题,不知道 ios。不过你可以试一试。

以上是关于cordova pushplugin 无法在 iOS 中获取设备令牌的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中使用 PushPlugin for Cordova 清除单个通知

iOS Cordova PushPlugin

iOS PushPlugin Cordova 注册问题

使用 IOs-PushPlugin Cordova 2.5 进行首次推送

如何在cordova android上连接PushPlugin + Parse

PushPlugin“不存在”Cordova 3.5