iosswiftpush-notification

My push notifications have not reached the iOS device for two days


I have stored device tokens in a database, to which I send messages via PHP. No push notifications have been received by any of the devices for two days. When I send the push message, I get the number of characters sent back in PHP. The device token sent is also correct. Nevertheless, my message does not arrive.

The request to the Feedback server does not bring any faulty device tokens.

Could it be that Apple generally blocks the push notifications because, for example, some device tokens are no longer available because the app has been deleted from the device?


Solution

  • I received the following email from Apple Support. Here is an excerpt from it:

    ...... Based on your reports that your Push Notifications have stopped working without any changes on your end, we suspect this could be due to continued use of the legacy Binary Interface which was retired March 31st, 2021 (https://developer.apple.com/news/?id=c88acm2b).

    This change requires you to migrate your push servers to use the HTTP/2 API. Any push servers still using the legacy interface will be unable to connect to APNs, resulting in Push Notifications not working.

    More information about the HTTP/2 provider API can be found in these two WWDC sessions:

    You can read more about the new APNs Provider API here: https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/ ........

    So I have now changed my PHP file and it works:

        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;
        }
    
    

    So you can call it:

        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); 
    

    it works fine.

    Create the key file 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)