我的推送通知已经两天没有到达 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 会议中找到:

您可以在此处阅读有关新 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)