首页 文章

推送通知未在iphone上接收

提问于
浏览
9

我正在使用 this tutorial 来学习推送通知 .

<?php

// Put your device token here (without spaces):
$deviceToken = '1675ba8bb005740bb514222227f861c30230a81e6eed6bb6b8f353c57831341d';

// Put your private key's passphrase here:
$passphrase = '111134';

// Put your alert message here:
$message = 'My first push notification!';

////////////////////////////////////////////////////////////////////////////////

 $ctx = stream_context_create();
 stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
 stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

 if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

 echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) .  $payload;

 // Send it to the server
 $result = fwrite($fp, $msg, strlen($msg));
 echo 'result =' . $result. PHP_EOL;
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;

 // Close the connection to the server
fclose($fp);

我还配置推送通知的应用程序 . 配置推送后,我还重新创建配置文件,旧删除一个,安装新的配置文件 . 我运行app它给我设备ID然后我连接服务器沙箱和 生产环境 发送推送通知与他们的相对推送配置文件但仍然我无法在我的设备上接收推送通知 .

我还在我的设备上安装ipusher并检查推送通知 . 他们来自那个应用程序 .

我注意到一个奇怪的事情是我更改了我的应用程序标识符并使用任何其他应用程序ID,然后设备令牌保持不变

现在我的问题是我没有在我的设备上收到推送通知 .


问题不在我的 Profiles 中 . 可能是错误是我正在使用的PHP代码,因为当我在远程服务器上使用简单的apns然后它发送推送通知 . 收到的通知时间为6到7个小时 . 我认为这是由于设备端的网络问题 . 但现在它在 生产环境 情况下2天后工作正常 . 现在,通知会立即在我的设备上发送,但在某些设备上需要30秒到5分钟 .


如果您没有从其他应用程序接收设备上的推送通知,则可能还有一个问题,那么您应该检查DNS以获取连接 .

5 回答

  • 1

    首先确保您使用的是:

    • 使用调试/发布提供编译应用程序

    • 您的钥匙串具有开发/ 生产环境 推送通知证书

    然后使用以下代码(已经过开发和 生产环境 测试)

    <?php
    // Comment these lines in production mode
    ini_set('display_errors','on');
    error_reporting(E_ALL);
    
    
    // Apns config
    
    // true - use apns in production mode
    // false - use apns in dev mode
    define("PRODUCTION_MODE",false);
    
    $serverId = 1;
    $serverName = 'my-server-domain.com';
    
    if(PRODUCTION_MODE) {
    $apnsHost = 'gateway.sandbox.push.apple.com';
    } else {
    $apnsHost = 'gateway.push.apple.com';
    }
    
    $apnsPort = 2195;
    if(PRODUCTION_MODE) {
    // Use a development push certificate 
    $apnsCert = $_SERVER['DOCUMENT_ROOT'].'/apns/apns-dominos-development.pem';
    } else {
    // Use a production push certificate 
    $apnsCert = $_SERVER['DOCUMENT_ROOT'].'/apns/apns-dominos-production.pem';
    }
    
    
    // --- Sending push notification ---
    
    // Insert your device token here 
    $device_token = "<dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8 dc6127d8    dc6127d8>"; // Some Device Token
    
    
    // Notification content
    
    $payload = array();
    
    //Basic message
    $payload['aps'] = array(
    'alert' => 'testing 1,2,3..', 
    'badge' => 1, 
    'sound' => 'default',
    );
    $payload['server'] = array(
    'serverId' => $serverId,
     'name' => $serverName
    );
    // Add some custom data to notification
    $payload['data'] = array(
    'foo' => "bar"
    );
    $payload = json_encode($payload);
    
    $streamContext = stream_context_create();
    stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
    stream_context_set_option($streamContext, 'ssl', 'passphrase', "");
    
    
    $apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error,      $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
    
    
    $deviceToken = str_replace(" ","",substr($device_token,1,-1));
    echo $deviceToken;
    $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '',      $deviceToken)) . chr(0) . chr(mb_strlen($payload)) . $payload;
    fwrite($apns, $apnsMessage);
    
    
    //socket_close($apns);
    fclose($apns);
    
    ?>
    
  • 2

    在服务器端实现反馈服务,并在服务器端检查所有设备令牌发送到APNS的持续时间 . 从反馈服务至少你会知道有多少设备收到你的通知 . 如果所有设备令牌一个接一个地发送到APN,并且APN没有通过反馈服务发送任何列表,那么你无法处理在设备上接收通知的持续时间 .

  • 8

    好吧,我终于得到了我的问题 . 问题不在代码实际上问题是在我的iPhone中设置错误的DNS值 . Iphone自动将我的路由器的ip放入DNS字段 . 现在我给我的服务提供商的DNS值,然后它工作正常 . 现在我发送推送消息后立即收到推送消息 .

    I Hope it helps others.

  • 1

    检查您的推送通知证书 . 证书是否与任何私钥相关联?

    如果不是,请使用从您的密钥链生成的适当私钥重新创建推送通知证书 .

    请看下面的教程:

    Apple Push Notification Tutorial:

    谢谢,

    MinuMaster

  • 2

    使用UrbanAirShip . 在我看来,它是最好的服务器端解决方案,因为它包括Android(C2DM)和Blakberry的推送式通知 .

    尝试找到这些文件之间的差异并理解它们 . 可能是你的问题的解决方案 . 这是我的代码:

    <?php
    
    $message = 'Hello'; // $_GET or $_POST
    $badge = 3; // int
    $sound = 'default'; // string - sound name
    $development = true; // boolean
    
    $payload = array();
    $payload['aps'] = array('alert' => $message, 'badge' => intval($badge), 'sound' =>    $sound);
    $payload = json_encode($payload);
    
    $apns_url = NULL; // Set Later
    $apns_cert = NULL; // Set Later
    $apns_port = 2195;
    
    if($development)
    {
        $apns_url = 'gateway.sandbox.push.apple.com';
        $apns_cert = '/path/apns.pem'; // relative address to an App Specific Certificate     file 
    }
    else
    {
        $apns_url = 'gateway.push.apple.com';
        $apns_cert = '/path/cert-prod.pem';
    }
    
    $stream_context = stream_context_create();
    stream_context_set_option($stream_context, 'ssl','local_cert',$apns_cert);
    
    $apns = stream_socket_client('ssl://'.$apns_url.':'.$apns_port,$error,$error_string,2,STREAM_CLIENT    _CONNECT,$stream_context);
    
    //  You will need to put your device tokens into the $device_tokens array yourself
    $device_tokens = array(); // tokens!!!
    
    foreach($device_tokens as $device_token)
    {
        $apns_message = chr(0).chr(0).chr(32).pack('H*',str_replace('    ','',$device_token)).chr(0).chr(strlen($payload)).$payload;
        fwrite($apns, $apns_message);
    }
    
    @socket_close($apns);
    @fclose($apns);
    ?>
    

相关问题