向iOS用户发送通知时,对于其中一些用户,我会收到响应状态码400(BadDeviceToken)或代码410(未注册)。
从Apple关于“BadDeviceToken”的文档:
指定的设备令牌很糟糕。验证请求是否包含有效令牌以及令牌是否与环境匹配。
“坏”是什么意思?我知道设备令牌在某些时候是有效的。用户如何使其设备令牌变坏?
从关于“未注册”的文档:
设备令牌对于指定的主题处于非活动状态。
这是否意味着应用程序已被删除?或者这种反应可能还有其他原因。
正如您在APNS文档中引用Table 8-6一样,错误有两种可能的原因:
如果是第一种情况,请确保iOS应用程序每次启动应用程序时都会注册设备以进行远程通知,因为有很多原因导致设备令牌在启动时发生变化,如Configuring Remote Notification Support中所述。
如果是第二种情况,您需要确保:
幸运的是,作为iOS开发人员,您不需要自己直接更改APNS权利。它始终处于开发阶段,只有在为App Store或企业分发生成构建和导出时,Xcode才会自动将其更改为生产。至于后端,您的后端开发人员应该知道如何为开发和生产环境配置后端。对于某些框架,这是一个切换一些名为isProduction
的布尔值的问题。最终,根据Communicating with APNs的APNs Connections
部分,推送通知将发送到不同的APNS端点,具体取决于环境是生产还是开发。
让我们假装BadDeviceToken
错误是由第二种情况引起的 - 应用程序注册的设备令牌与后端正确配置的开发环境不匹配。首先,在您的Xcode项目中,检查您的.entitlements
文件并验证APS Environment
密钥的值是development
。它应该如下所示:
接下来,在生成存档后,打开管理器(通过Window
菜单> Organizer
),选择存档,然后单击右侧的Export...
。您应该看到四种分发方法:
如果您选择App Store或Enterprise,您将在后面的对话框中看到Xcode将APNS权利更改为生产(请参阅红色箭头的提示):
如果选择Ad Hoc或Development,则aps-environment下的文本将为development
,然后应与后端的配置匹配。
状态代码“400”:当您尝试使用错误的证书发送通知时,会出现此错误。确保将生产证书用于生产环境。这很糟糕,因为您使用了错误的配置。
状态代码'410':是的,使用此代码我们可以理解应用已删除。在我们的app中获取此状态代码时,我们会从db中删除此令牌。另一种情况可能是用户重新安装了可能会更改其令牌的应用程序。所以你删除这个令牌会更好。
错误代码404:BadDevice令牌
可能的原因:
注意:使用您的bundleid附加.voip以发送voip推送通知(例如:bundleid.voip)
这是一个可行的voip推送通知示例:
<?php
$token = $_REQUEST['tok'];
if (!defined('CURL_HTTP_VERSION_2_0')) {
define('CURL_HTTP_VERSION_2_0', 3);
}
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send push
$apple_cert = 'certificate_name.pem';
$message = '{"aps":{"action":"message","title":"your_title","body":"your_message_body"}}';
$http2_server = 'https://api.development.push.apple.com'; // or 'api.push.apple.com' if production
$app_bundle_id = 'your bundle id';
$status = sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token);
echo $status;
// close connection
curl_close($http2ch);
function sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token)
{
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
$cert = realpath($apple_cert);
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
"User-Agent: My Sender"
);
curl_setopt_array($http2ch, array(
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLCERT => $cert,
CURLOPT_HEADER => 1
));
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
// get response
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
if($status=="200")
echo "SENT|NA";
else
echo "FAILED|$status";
}
?>