PHP对接IOS原生推送APNS通知

此方法使用的是JWT令牌模式,2024-05-08亲测可用
要求:服务器必须支持http2或者发送请求的插件支持(不支持或者不懂自行百度即可)
自行替换keyId和teamId
本代码示例用到了redis(APNS的jwt有效期规定不能超过1小时,需要及时更新),如不需要或者使用别的缓存请自行删除替换
ios推送文档地址(英文):文档地址

注意事项:一定要保存好.p8文件(苹果那边只让下载一次,丢了就要重新生成)
注意事项:一定要保存好.p8文件(苹果那边只让下载一次,丢了就要重新生成)
注意事项:一定要保存好.p8文件(苹果那边只让下载一次,丢了就要重新生成)

PS:其他语音可自行复制代码,让AI转换然后调试即可
不废话直接上代码:

<?php
/**
 * @desc
 * @datatime 2024/5/6 11:16
 */

namespace app\wtx_app\controller\app_push;

use redis\RedisDb;
use think\Controller;

class TestPush extends Controller
{
    protected static $cacheKey  = 'jwt-cache-key';
    protected static $cacheTime = 1800;
    protected static $keyId  = '10位数的keyId';//keyId
    protected static $teamId = '团队ID';//团队ID
    public function testPush(){
        $deviceToken = '';  //推送给谁给
        //方式1
        $payload = [
            'aps'=>[
                'alert'=>[
                    'title'    =>'消息提醒标题',
                    'subtitle' =>'字幕',
                    'body'     =>'具体话术',
                ],
                'badge'=>1//角标展示数量
            ],
            'ziDingYi1'  =>112,//自定义参数1
            'ziDingYi2'  =>['type'=>'ce'],//自定义参数2
        ];
        //方式2
        $payload = [
            'aps'=>[
                'alert'=>'具体话术',
                'badge'=>1,
            ],
            'ziDingYi1'  =>112,//自定义参数1
            'ziDingYi2'  =>['type'=>'ce'],//自定义参数2
        ];
        $payloadJson = json_encode($payload);

        //推送地址【沙箱环境:https://api.sandbox.push.apple.com:443正式环境:https://api.push.apple.com:443】
        $url = \think\facade\Env::get('ios_push_token_url','https://api.push.apple.com:443')."/3/device/".$deviceToken;

        //通知类型或者内容一致的话可以设置此值为固定(可以不传,IOS会随机)
        $collapseId = md5('push-ios');
        $headers = array(
            'Authorization: bearer '.$this->getJwt(),//jwt的token令牌
            'Content-Type: application/json',
            'apns-push-type: alert',//推送类型
            'apns-topic: app.xcxapp',//推送给那个app(包名)
            'apns-priority: 10',//通知重要程度(1-10,值越高越重要)
            'apns-expiration: 0',
            'apns-collapse-id: '.$collapseId,
        );
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);//这里很关键,以http2发送请求
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取响应内容
        curl_setopt($ch, CURLOPT_POST, true); // 表示这是一个POST请求
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payloadJson);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_HEADER, true);//获取HEADERS响应头否则就获取不到apns的响应信息(apns-id和apns-unique-id)
        $response  = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        echo "<pre>";
        // Check the response
        if ($http_code == 200) {
            // 分割响应头字符串为行
            $headerLines = explode("\n", $response);
            // 初始化变量来存储apns-id和apns-unique-id
            $apnsId       = '';
            $apnsUniqueId = '';

            // 遍历每行
            foreach ($headerLines as $line) {
                // 检查行是否包含apns-id或apns-unique-id
                if (strpos($line, 'apns-id:') !== false) {
                    // 提取apns-id
                    $apnsId = trim(str_replace('apns-id:', '', $line));
                }
                //apns-unique-id仅开发环境会返回
                if (strpos($line, 'apns-unique-id:') !== false) {
                    // 提取apns-unique-id
                    $apnsUniqueId = trim(str_replace('apns-unique-id:', '', $line));
                }
            }

            // 输出结果
            echo "apns-id: " . $apnsId . "\napns-unique-id: " . $apnsUniqueId;
            echo "<br>";
            echo 'SUCCESS';
        } else {
            echo 'ERROR_CODE: ' . $http_code;
        }
    }
    private function getJwt(){
        $redis    = RedisDb::getRedis();
        if($redis->exists(self::$cacheKey)){
            return $redis->get(self::$cacheKey);
        }
        //p8文件地址
        $pkeyFile = '.p8'; //p8证书文件,我在这里填的绝对地址

        // token过期时间
        $expires = time() + self::$cacheTime;

        // Generate the JWT header
        $header = array(
            'alg' => 'ES256',
            'kid' => self::$keyId
        );
        $jwtHeader = base64_encode(json_encode($header));

        // Generate the JWT payload
        $payload = array(
            'iss' => self::$teamId,
            'iat' => time(),
            'exp' => $expires,
            'aud' => 'https://appleid.apple.com',
        );
        $jwtPayload = base64_encode(json_encode($payload));

        //载入证书文件
        $pkeyContents = file_get_contents($pkeyFile);
        $pkey = openssl_get_privatekey($pkeyContents);

        //JWT 签名
        $signature = '';
        openssl_sign($jwtHeader . '.' . $jwtPayload, $signature, $pkey, 'sha256');
        $jwtSignature = base64_encode($signature);

        // Generate the final JWT
        $jwt = $jwtHeader . '.' . $jwtPayload . '.' . $jwtSignature;

        // Print the JWT
        $redis->set(self::$cacheKey, $jwt, self::$cacheTime);
        return $jwt;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值