我的推送通知已经两天没有到达 iOS 设备
My push notifications have not reached the iOS device for two days
我已将设备令牌存储在数据库中,我通过 PHP 向其发送消息。两天来任何设备都没有收到推送通知。当我发送推送消息时,我得到 PHP 中发回的字符数。发送的设备令牌也是正确的。然而,我的消息没有到达。
对反馈服务器的请求没有带来任何错误的设备令牌。
会不会是 Apple 通常会阻止推送通知,因为例如某些设备令牌不再可用,因为应用程序已从设备中删除?
请记住,APN 证书会在 1 年后过期,我遇到过这种情况!
我收到了来自 Apple 支持的以下电子邮件。以下是摘录:
……
根据您的报告,您的推送通知已停止工作,您端没有任何更改,我们怀疑这可能是由于继续使用已于 2021 年 3 月 31 日停用的旧版二进制接口 (https://developer.apple.com/news/?id=c88acm2b)。
此更改要求您迁移推送服务器以使用 HTTP/2 API。任何仍在使用旧接口的推送服务器将无法连接到 APNs,从而导致推送通知无法正常工作。
有关 HTTP/2 提供商 API 的更多信息可以在以下两个 WWDC 会议中找到:
- WWDC2015 通知中的新增内容https://developer.apple.com/videos/play/wwdc2015/720/
- WWDC2016 Apple 推送通知服务的新增功能https://developer.apple.com/videos/play/wwdc2016/724/
您可以在此处阅读有关新 APNs 提供商 API 的更多信息:
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/
.........
所以我现在更改了我的 PHP 文件并且它有效:
function sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token) {
//////////////////////////////////////////////
// @param $http2ch the curl connection
// @param $http2_server the Apple server url
// @param $apple_cert the path to the certificate
// @param $app_bundle_id the app bundle id
// @param $message the payload to send (JSON)
// @param $token the token of the device
// @return mixed the status code
///////////////////////////////////////////////
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
// certificate
$cert = realpath($apple_cert);
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
"User-Agent: My Sender"
);
// other curl options
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
));
// go...
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
// get response
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
return $status;
}
所以你可以这样称呼它:
include_once './sendHTTP2Push.php';
error_reporting(E_ALL);
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send push
$apple_cert = 'pem4.pem';
$message = '{"aps":{"alert":"Hi!","sound":"default"}}';
$token = 'c4942de20b30792b8f1e04c2f5488e05a24bf72f14f1fc849e6581faf9571111';
$http2_server = 'https://api.development.push.apple.com'; // or 'api.push.apple.com' if production
$app_bundle_id = 'com.gl.xxxxxxxx';
$status = sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token);
echo "Response from apple -> {$status}\n";
// close connection
curl_close($http2ch);
它工作正常。
创建密钥文件pem4.pem
Create a push certificate on the Apple site under Certificates and download it ---> aps-XX.cer
Call up keychain management
Insert the downloaded file
Apple Push Service: Export Com.gl.xxxxxxxx ---> xxx.p12
Call the terminal program
cd desktop
openssl pkcs12 -clcerts -nodes -out pem4.pem -in xxx.p12
Copy pem4.pem to the server
this is now @param $ apple_cert (see below)
我已将设备令牌存储在数据库中,我通过 PHP 向其发送消息。两天来任何设备都没有收到推送通知。当我发送推送消息时,我得到 PHP 中发回的字符数。发送的设备令牌也是正确的。然而,我的消息没有到达。
对反馈服务器的请求没有带来任何错误的设备令牌。
会不会是 Apple 通常会阻止推送通知,因为例如某些设备令牌不再可用,因为应用程序已从设备中删除?
请记住,APN 证书会在 1 年后过期,我遇到过这种情况!
我收到了来自 Apple 支持的以下电子邮件。以下是摘录:
…… 根据您的报告,您的推送通知已停止工作,您端没有任何更改,我们怀疑这可能是由于继续使用已于 2021 年 3 月 31 日停用的旧版二进制接口 (https://developer.apple.com/news/?id=c88acm2b)。
此更改要求您迁移推送服务器以使用 HTTP/2 API。任何仍在使用旧接口的推送服务器将无法连接到 APNs,从而导致推送通知无法正常工作。
有关 HTTP/2 提供商 API 的更多信息可以在以下两个 WWDC 会议中找到:
- WWDC2015 通知中的新增内容https://developer.apple.com/videos/play/wwdc2015/720/
- WWDC2016 Apple 推送通知服务的新增功能https://developer.apple.com/videos/play/wwdc2016/724/
您可以在此处阅读有关新 APNs 提供商 API 的更多信息: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/ .........
所以我现在更改了我的 PHP 文件并且它有效:
function sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token) {
//////////////////////////////////////////////
// @param $http2ch the curl connection
// @param $http2_server the Apple server url
// @param $apple_cert the path to the certificate
// @param $app_bundle_id the app bundle id
// @param $message the payload to send (JSON)
// @param $token the token of the device
// @return mixed the status code
///////////////////////////////////////////////
// url (endpoint)
$url = "{$http2_server}/3/device/{$token}";
// certificate
$cert = realpath($apple_cert);
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
"User-Agent: My Sender"
);
// other curl options
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
));
// go...
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($http2ch));
}
// get response
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
return $status;
}
所以你可以这样称呼它:
include_once './sendHTTP2Push.php';
error_reporting(E_ALL);
// open connection
$http2ch = curl_init();
curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
// send push
$apple_cert = 'pem4.pem';
$message = '{"aps":{"alert":"Hi!","sound":"default"}}';
$token = 'c4942de20b30792b8f1e04c2f5488e05a24bf72f14f1fc849e6581faf9571111';
$http2_server = 'https://api.development.push.apple.com'; // or 'api.push.apple.com' if production
$app_bundle_id = 'com.gl.xxxxxxxx';
$status = sendHTTP2Push($http2ch, $http2_server, $apple_cert, $app_bundle_id, $message, $token);
echo "Response from apple -> {$status}\n";
// close connection
curl_close($http2ch);
它工作正常。
创建密钥文件pem4.pem
Create a push certificate on the Apple site under Certificates and download it ---> aps-XX.cer
Call up keychain management
Insert the downloaded file
Apple Push Service: Export Com.gl.xxxxxxxx ---> xxx.p12
Call the terminal program
cd desktop
openssl pkcs12 -clcerts -nodes -out pem4.pem -in xxx.p12
Copy pem4.pem to the server
this is now @param $ apple_cert (see below)