【问题标题】:iOS - What are the common reasons for no Push NotificationsiOS - 没有推送通知的常见原因是什么
【发布时间】:2016-10-06 03:33:48
【问题描述】:

这可能是一个老问题,但我仍然想知道少数用户没有收到推送通知的几个原因,而不是全部。

我已经在一个应用程序中实现了 Push,它适用于 Development ProfileAdhoc ProfileDistribution Profile。所有设置和配置都非常谨慎地完成,并且可以正常工作。但即使启用了推送并授予了权限,也并非适用于所有人。

我保留 3 台设备和所有 3 个配置文件,我使用 TestFlight 作为分发配置文件。

现在通过 api,我们将 gateway.push.apple.com 用于 AdhocTestFlight 构建,以及 gateway.sandbox.push.apple.com 对于开发,我们也尝试过改变这些。但我们仍然无法使其适用于所有用户。

我们缺少什么具体的东西吗?

更新

这就是我们的Payload 的样子

aps = {
        alert = "New message from iphonic";
        badge = 1;
        eventid = 76;
        notifytype = message;
        senderuserid = 0;
        sound = default;
};

谢谢。

【问题讨论】:

  • 您提到您已经创建了开发、临时和分发配置文件,但您还应该将其提供给您的 php 开发人员,并在您的项目中进行一些更改,例如为远程通知设置后台模式
  • 检查您的 .pem 文件。您使用什么类型的推送通知证书来创建它们。 APNS 开发或 APNS 分发..
  • @BhumeshPurohit 为什么 PHP 开发人员需要配置文件,他们只需要 .pem 文件,不是吗?你还有什么意思吗?
  • @BhushanVU PEM 文件是正确的,因为有些设备可以接收通知但不是全部。
  • 好的。我们可以尝试通过编写测试脚本来跟踪它,只输入无法接收推送通知的设备的单个设备令牌。只需发送一个简单的文本并确保应用程序在后台运行或在运行该测试脚本之前终止。

标签: php ios objective-c swift apple-push-notifications


【解决方案1】:

可能会出现几个问题:

  1. 收到了一些通知,但不是全部:如果您要发送多个 同时推送通知,只收到几个,害怕 不是!那是预期的行为。 APNS 维护一个 QoS (Quality of 服务)每个设备的队列与推送应用程序。这个尺寸 queue 是 1,所以如果你发送多个通知,最后一个 通知被覆盖。
  2. 连接到推送通知服务的问题:一种可能性 可能是有防火墙阻止了 APNS 使用的端口。 确保取消阻止这些端口。另一种可能是 私钥和 CSR 文件错误。请记住,每个 App ID 具有唯一的 CSR 和私钥组合。

【讨论】:

    【解决方案2】:

    虽然还有其他原因,但在很大比例的情况下,推送失败的原因是由于推送“方程式”已被打破。

    有两个等式,必须完全遵循其中一个才能使推送起作用。

    发展方程:

    App + Development APN token + Development 的开发构建 证书 + 开发 Apple 网关 == 成功

    生产方程:

    应用程序的生产版本 + 生产 APN 令牌 + 生产 证书 + 生产 Apple 网关 == 成功。

    如果生产方程中有任何开发元素,或者开发方程中有任何生产元素,则推送将不起作用。等式的所有四个元素都必须是全部开发或全部生产。

    当您通过 Xcode 运行应用程序时,默认情况下它将是应用程序的开发版本(可以在方案中更改,但除非您知道这一点并且已经这样做,否则它将是调试版本),因此在使用Xcode 你必须使用开发方程来实现推送功能。如果您创建一个临时分发或应用商店构建,那么它将是一个生产构建,您必须使用生产方程式才能使其工作。

    如果创建广告/分发/应用商店构建等,那么失败的常见原因是未在构建设置中正确设置 Xcode 的代码签名和配置文件部分。

    此外,应用程序的生产版本和应用程序的开发版本会产生不同的推送令牌,因此如果您暂时将令牌硬编码到某些服务器测试脚本或类似脚本中,则必须确保其令牌正确.在旧版本的 iOS 中,一旦你获得了令牌,它就永远不会改变(它们可以,但这种情况很少见)。但在 iOS9 中,情况不再如此,令牌可以而且确实会发生变化,因此请始终确保您在服务器上使用的令牌是最新的。

    推送也必须通过正确的网关发送,Apple 开发网关是沙盒网关:

    ssl://gateway.sandbox.push.apple.com:2195

    而生产网关是:

    ssl://gateway.push.apple.com:2195

    使用生产网关时,服务器当然必须使用生产证书签名,使用沙盒网关时使用开发证书签名。

    如果您对两个证书使用相同的密码,那么您可以使用同一 .pem 文件中的生产证书和开发证书对您的服务器进行签名。 IE。您可以将所有提升证书和密钥连接到单个 .pem 文件中,并使用该文件对服务器进行签名。在使用 Xcode 进行测试时,服务器当然需要使用沙盒网关,而在最终应用商店发布时需要使用生产网关。

    【讨论】:

    • 感谢您提供的信息,我们正在关注您在此处定义的所有专业,分离开发和生产环境,更新令牌等,并且 .pem 文件也是正确的,如果我们不能满足所有任何设备都不会接收推送,80% 的设备都接收。
    • 如果您 100% 确定所有 3 台设备上的构建都是相同的(当然,在设备上启用了推送)并且推送会交付给某些人而不是其他人,那么唯一的变量是推送令牌。您如何将推送令牌从设备获取到服务器?还是前台推送还是后台推送? (即,定向到用户的推送还是定向到应用的推送?)
    • 我 200% 确定。我们有 api 在每次启动时将 push_tokes 更新到服务器数据库,当应用程序未运行时它的后台推送。
    • "当应用程序未运行时" 如果应用程序未运行,后台推送不会传送到应用程序。 “未运行”是指应用程序已终止还是其
    • 当应用程序处于后台或未运行时,推送将显示通知。由于明显的原因,它甚至在前台都不起作用。
    【解决方案3】:

    使用它来发送测试通知。并且不要忘记将 .pem 也添加到服务器,而不仅仅是 .php 文件

    <?php
    
    // Put your device token here (without spaces):
    $deviceToken = '';
    
    // Put your private key's passphrase here:
    $passphrase = '';
    
    // Put your alert message here:
    $message = 'Salut!';
    
    ////////////////////////////////////////////////////////////////////////////////
    
    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', 'yourFile.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));
    
    if (!$result)
        echo 'Message not delivered' . PHP_EOL;
    else
        echo 'Message successfully delivered' . PHP_EOL;
    
    // Close the connection to the server
    fclose($fp);
    

    【讨论】:

      【解决方案4】:

      在设备上没有收到推送通知有以下原因:

      1. 证书的密码和服务器端代码中添加的密码不同。
      2. 推送通知有效负载的大小超出。根据苹果标准,它应该低于 2048 KB。它被称为有效载荷。如果您的负载(通知对象)大小大于 2048 KB,那么 APNS 将不会处理它,因此设备也不会得到它。
      3. 从 iPhone 应用程序发送到服务器的设备令牌错误。参考Get device token
      4. 最后,如果服务器正在为 iOS 和 Android 发送推送通知,那么请确保您正在向正确的设备发送通知,因为 iOS 将从 APNS 获取它,而 android 将从 GCM 获取它。在这种情况下,注册时您可以从用户那里获取设备类型并将其保存在您的数据库中。所以它可以在发送通知时使用。

      在我看来,这些是可能的情况。让我知道它是否适合您或现在。

      【讨论】:

      • 感谢您的回答。 1. 没有所有信息都是正确的,因为它有效,但并非全部。 2. 我们只发送了“Hi”作为有效载荷。 3.有什么方法可以知道设备令牌是否错误? 4. Android和iOS分开处理所以这不是问题,而且Android可以接收罚款。
      • 如果它在 android 中运行良好,那么可能有 2 种情况 1. 有效负载的大小超过 2. 错误的设备令牌。答案中提到了获取设备令牌的工作代码。而且我们无法验证设备令牌。
      • 我已经更新了我的问题中的有效负载,不认为这超出了,其他情况是什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 2020-04-18
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多