APNS推送通知不适用于生产

时间:2014-03-28 15:39:56

标签: ios xcode apple-push-notifications push

我创建了一个App来从Web服务器发送远程通知。 当我在开发模式下测试应用程序时,所有通知都在手机上正确到达,在AppStore发布后,应用程序不再收到通知。

这就是我所做的:

  1. 创建了一个用于生产的私钥和一个用于开发的私钥。
  2. 通过传递先前生成的CertFile,在我的App ID上生成两个SSL证书。我100%确定已正确生成2个密钥并正确传递它们以从App中的Dev Center下载SSL证书。
  3. 创建了一个用于开发的文件.pem和一个用于生成的文件(通过转换从我的KeyChain中提取的文件.p12等)。
  4. 为开发创建了2个不同的配置文件,为连接到步骤1的AppID的生产创建了一个。
  5. 使用在步骤4中创建的正确配置文件在Build Settings中签名应用程序。
  6. 创建了一个Web应用程序来捕获和存储用户令牌。
  7. 创建了一个测试推送通知发送的php页面。
  8. 这是我测试的内容:

    1. 使用沙盒链接上的telnet测试了开发生成的.pem文件,并获得了成功的答案。
    2. 在生产链接上使用telnet测试了生产生成的.pem文件并获得了成功的答案。
    3. 我百分百肯定已经在我的网络应用程序中存储了我的iPhone的开发令牌。
    4. 我百分百肯定已经在我的网络应用服务器上存储了我的iPhone的制作令牌。
    5. 我100%肯定会将我的php页面传递给Apple Server正确的消息(用于开发和生产)。
    6. php页面始终从Apple Server返回成功的消息(用于开发和生产)。
    7. 以下是我在Xcode上签署应用的方式:

      enter image description here enter image description here enter image description here enter image description here

      以下是发送通知的php页面的代码:

          $ctx = stream_context_create();
      
          //stream_context_set_option($ctx, 'ssl', 'passphrase', 'development_pwd');
          //stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck_development.pem');
          //$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); //test
      
          stream_context_set_option($ctx, 'ssl', 'passphrase', 'production_pwd');
          stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck_production.pem');
          $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); //production
      
          echo "<p>Connection Open</p>";
          if(!$fp){
              echo "<p>Failed to connect!<br />Error Number: " . $err . " <br />Code: " . $errstrn . "</p>";
              return;
          } else {
              echo "<p>Sending notification!</p>";    
          }
      
          $i = 0;
      
          foreach ($deviceToken as $dt) {
              $dt = str_replace(' ' , '' , $dt);
              $msg = chr(0) . pack('n',32) . pack('H*', $dt) . pack('n',strlen($payload)) . $payload;
              echo "<p>" . $i . " - Message sent: " . $payload . "<br />Token: ". $dt . "<br />***" . $msg . "***</p>";
              $result = fwrite($fp, $msg, strlen($msg));
              $i++;
              if (!$result)
                  echo '<p>Message not delivered ' . PHP_EOL . '!</p>';
              else
                  echo '<p>Message successfully delivered ' . PHP_EOL . '!</p>';
          }
          fclose($fp);
          echo "<p>Total Notifications Sent: " . $i . "</p>";
          echo "<p>Connection Closed!</p>";
      }
      ?>
      

      结论: 我的PC上有测试应用程序,可以接收APNS推送通知。 我在App Store上发布的应用程序完全相同,但没有收到APNS推送通知。

      我真的竭尽全力解决这个问题并阅读了大约数千页的论坛,stackoverflow和Apple Documentations。

      我愿意帮助每个帮助我找到问题解决方案的人!

4 个答案:

答案 0 :(得分:16)

您提到的链接是Sandbox APNS链接。生产APNS链接是根据Apple documentation

  

您可以访问 gateway.push.apple.com 的制作环境,   出站TCP端口2195。

要验证的事情很少:

  1. 您的AppId已启用分发APNS。
  2. 您已创建分发APNS SSL证书并已安装在您的构建计算机上(用于App Store提交)。
  3. 您已在服务器上的步骤2中安装了SSL证书。
  4. 您没有错误地使用开发APNS SSL证书。

答案 1 :(得分:13)

生产和沙盒的设备令牌对于同一设备是不同的。

因此,尝试使用Adhoc或Distribution证书获取设备令牌,并在生产中使用生成的令牌,这对我有用。

答案 2 :(得分:1)

我刚遇到同样的问题。推送通知到达开发模式,而不是生产。我也检查了几次,确信一切都很好。

但事实并非如此。这是这个过程的第一步。创建csr。我确信我没有必要为开发和生产创建一个csr文件,并最终为两个证书使用相同的csr文件。没有工作......

也许将来有人会犯同样的错误并节省一些时间。

答案 3 :(得分:0)

如果您使用的是Google Firebase云消息传递工具,请检查

1)确保与您的服务器团队一起,将服务器从开发更改为生产。

2)您的生产APN的证书(转换为.p12文件)是否已上传。

3)确保未从钥匙串访问中使用密钥导出.p12文件。(like this

4)如果已经上传,则检查生产APN的证书的到期日期。 Google FCM会在生产APN的证书到期之日起2个月之前拒绝该证书。