ios APNS 推送通知不适用于生产

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22717275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:51:22  来源:igfitidea点击:

APNS Push Notifications Not Working on Production

iosxcodeapple-push-notificationspush

提问by prelite

I created an App to send remote notifications from a web server. When I tested the App in Development Mode all the notifications arrived correctly on the phone, after the AppStore release the app did not receive notifications anymore.

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

Here it is what I did:

这是我所做的:

  1. Created a Private Key For Production and one for development.
  2. Generated on my App ID two SSL Certificates by passing the previous CertFile Generated. I'm 100% sure to have generated correctly 2 key and passed them correctly to download the SSL Cert from Dev Center under AppID.
  3. Created a file .pem for development and one for production (by converting the file .p12 extracted from my KeyChain etc etc).
  4. Created 2 different provisioning profile one for development and one for production connected to the AppID of step 1.
  5. Signed the app in Build Settings with the correct Provisioning Profiles created in step 4.
  6. Created a Web App to catch and store users Tokens.
  7. Created a php page to test Push Notification Sending.
  1. 为生产创建了一个私钥,为开发创建了一个私钥。
  2. 通过传递先前生成的 CertFile 在我的 App ID 上生成两个 SSL 证书。我 100% 确定已正确生成 2 个密钥并正确传递它们以从 AppID 下的开发中心下载 SSL 证书。
  3. 创建了一个用于开发的文件 .pem 和用于生产的文件(通过转换从我的 KeyChain 等中提取的文件 .p12 等)。
  4. 创建了 2 个不同的配置文件,一个用于开发,一个用于生产连接到步骤 1 的 AppID。
  5. 使用在步骤 4 中创建的正确配置文件在构建设置中对应用程序进行签名。
  6. 创建了一个 Web 应用程序来捕获和存储用户令牌。
  7. 创建了一个 php 页面来测试推送通知发送。

Here it is what i tested:

这是我测试的:

  1. Tested the development generated .pem file with telnet on sandbox link with a succesfull answer.
  2. Tested the production generated .pem file with telnet on production link with a succesfull answer.
  3. I'm 100% sure to have stored on my web app the development token of my iPhone.
  4. I'm 100% sure to have stored on my web app server the production token of my iPhone.
  5. I'm 100% sure to pass with my php page the right message to Apple Server (both for development and production).
  6. The php page always return a succesfull message from Apple Server (both for development and production).
  1. 使用沙箱链接上的 telnet 测试了开发生成的 .pem 文件,并获得了成功的答案。
  2. 使用 telnet 在生产链接上测试了生产生成的 .pem 文件,并获得了成功的答案。
  3. 我 100% 肯定已将 iPhone 的开发令牌存储在我的网络应用程序中。
  4. 我 100% 肯定已将 iPhone 的生产令牌存储在我的 Web 应用程序服务器上。
  5. 我 100% 肯定会通过我的 php 页面将正确的消息传递给 Apple Server(用于开发和生产)。
  6. php 页面总是从 Apple Server(用于开发和生产)返回成功消息。

Here is how I sign the app on Xcode:

以下是我在 Xcode 上签署应用程序的方法:

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

在此处输入图片说明在此处输入图片说明在此处输入图片说明在此处输入图片说明

Here is the code of the php page to send notifications:

这是发送通知的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>";
}
?>

Conclusions: I have the Test App on my PC that receive APNS Push Notifications. I have the exactly same app released on App Store that not receive APNS Push Notifications.

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

I realy made everything in my power to fix this issue and read about thousand pages of forums, stackoverflow and Apple Documentations.

我真的尽我所能来解决这个问题,并阅读了大约数千页的论坛、stackoverflow 和 Apple 文档。

I'm willing to retribuite everyone of you who helps me find the solution to my issue!

我愿意回报所有帮助我找到问题解决方案的人!

回答by gagarwal

The link you mentioned is Sandbox APNS link. Production APNS link is as per Apple documentationis:

您提到的链接是 Sandbox APNS 链接。根据 Apple文档,生产 APNS 链接是:

You access the production environment at gateway.push.apple.com, outbound TCP port 2195.

您通过gateway.push.apple.com访问生产环境,出站 TCP 端口 2195。

Few things to verify:

需要验证的几件事:

  1. Your AppId is enabled for Distribution APNS.
  2. You have created Distribution APNS SSL Certificate and is installed on your build machine (for App Store submission).
  3. You have installed the SSL Certificate in step 2 on your server.
  4. You are not by mistake using Development APNS SSL Certificate.
  1. 您的 AppId 已启用分发 APNS。
  2. 您已创建分发 APNS SSL 证书并安装在您的构建机器上(用于 App Store 提交)。
  3. 您已在服务器上安装了步骤 2 中的 SSL 证书。
  4. 您没有错误地使用开发 APNS SSL 证书。

回答by Ravindra Naik

Device token for Production and Sandbox are different for same device.

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

So try getting device token by using Adhoc or Distribution certificates and use the generated token on production, this worked for me.

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

回答by butters

I Just came across the same problem. Push Notifications are arriving in Development Mode, not in Production. I also checked everything a few times and was sure that everything was fine.

我刚遇到同样的问题。推送通知以开发模式而非生产模式到达。我还检查了几次,并确定一切都很好。

But it wasn't. It was the very first step in the process. Creating the csr. I was sure I didn't have to create a csr file for Development and Production and ended up using the same csr file for both certificats. Didn't work...

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

Maybe someone in future does the same mistake und saves some time now.

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

回答by M VIJAY

If you work with the Google Firebase Cloud Messaging means, Kindly check

如果您使用 Google Firebase Cloud Messaging 方式,请检查

1) Make sure with your server team, your server is changed from development to the production.

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

2) Your production APN's certificate(convert into .p12 file) is uploaded or not.

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

3) Make sure the .p12 file is not exported with the key from the Keychain access.(like this)

3) 确保 .p12 文件没有与钥匙串访问中的密钥一起导出。(像这样

4) If it is uploaded already, then check production APN's certificate's expiry date. Google FCM rejects the certificates before 2 months from the expiry of production APN's certificate.

4) 如果已经上传,则检查生产APN 的证书的到期日期。Google FCM 会在生产 APN 的证书到期后 2 个月内拒绝这些证书。