使用 PHP 發送 iOS 遠距推播

2023版使用 PHP 發送 iOS 遠距推播 的範例.
重點 :
1. php curl 要支援 HTTP/2
2.本文使用的是開發者帳號申請的 p8格式的金鑰
基本設定值 : config.php

<?php
    $team_id="開發者帳號的TEAM ID";
    $key_id="p8金鑰的 Key ID"; 
    $pkey_file="p8 格式的金鑰檔名,絕對路徑";
    $topic="App的Bundle ID";

主程式 :

<?php
require_once "config.php";
    
function Sent_Notification_iOS($team_id ,$key_id,$pkey_file,$topic,$device_token,$payload,$sandbox=false){

    $payload = json_encode($payload);

    if ($sandbox == true){
        //沙盒推送地址
        $url = "https://api.sandbox.push.apple.com/3/device/".$device_token;		
    }else{
        //正式環境推送
        $url = 'https://api.push.apple.com/3/device/' . $device_token;
    }

    
    $jwt = get_JWT($team_id ,$key_id,$pkey_file,$topic);
        
    $headers = array(
        'Authorization: Bearer '.$jwt,
        'Content-Type: application/json',
       	'apns-topic: '.$topic,
    );
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); //這里很關鍵,以http2發送請求
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // Check the response
    /*
    if ($http_code == 200) {
        return 'Notification sent successfully.';
    } else {
        echo 'Notification failed with error code: ' . $http_code;
    }
    */
    return $http_code;
}
function get_JWT($team_id ,$key_id,$pkey_file,$TOPIC){

// token過期時間
    $expires = time() + 3600;

    // Generate the JWT header
    $header = array(
        'alg' => 'ES256',
        'kid' => $key_id
    );

    $jwt_header = base64_encode(json_encode($header));

    // Generate the JWT payload
    $payload = array(
        'iss' => $team_id,
        'iat' => time()
    );
    $jwt_payload = base64_encode(json_encode($payload));

    //載入證書文件
    $pkey_contents = file_get_contents($pkey_file);
    $pkey = openssl_get_privatekey($pkey_contents);

    //JWT 簽名
    $signature = '';
    openssl_sign($jwt_header . '.' . $jwt_payload, $signature, $pkey, 'sha256');
    $jwt_signature = base64_encode($signature);
    
    // Generate the final JWT
    $jwt = $jwt_header . '.' . $jwt_payload . '.' . $jwt_signature;
    return $jwt;
}

發送範例 :

<?php
require_once "iOS_Notification.php";

    $device_token="接收端設備碼";//接收端設備碼
    
$msg=array(
        'aps' => array(
                'alert' => array (
                            "title" => "非洲大草原",
                            "subtitle" => "肯亞",
                            "body" => "大象一隻"
                           ),
                 'badge' => 99,
                 'sound' => "default"
        )
);
    
$r=Sent_Notification_iOS($team_id ,$key_id,$pkey_file,$topic,$device_token,$msg);

在 App 內清除或設定 Badge :

UIApplication.shared.applicationIconBadgeNumber = 0

 

Payload 各項設定參考資料 :
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification