【问题标题】:Apple PNS (push notification services) sample codeApple PNS(推送通知服务)示例代码
【发布时间】:2010-11-06 08:41:37
【问题描述】:

是否有示例项目显示如何在 iPhone 上使用 APNS 以及如何设置?我目前正在查看文档,但如果有一些工作代码可以分开并查看它们是如何协同工作的,那就太好了?

我似乎无法使用谷歌或在 iphone 开发中心找到任何东西。

【问题讨论】:

  • 查看这里arashnorouzi.wordpress.com/2011/03/31/… 正是您要找的。​​span>
  • @froh42 你有满意的代码吗?我还想要逐步实施的示例代码。如果您有,请提供给我。提前谢谢你。

标签: iphone push-notification


【解决方案1】:

我知道这是一个非常古老的问题,并且已经收到了很多答案,但我发现Rey Wenderlich 的教程非常有用,并想分享给 APNS 初学者。它非常有用且非常容易理解。

【讨论】:

    【解决方案2】:

    试试 GitHub 上的 NWPusher 项目。它提供 OS X 和 iOS 应用程序手动发送推送通知,或者您可以直接使用包含的 Objective-C 库。

    【讨论】:

      【解决方案3】:

      设置推送通知服务最糟糕的部分是配置。我遇到的主要障碍是您从 Apple 网站下载的 .cer 文件中有一个证书和一个密钥,我用 C# 编写了一个发送通知的系统服务,并且连接一直失败,因为我已经导出了证书而不是关键。

      我不记得最初是谁写的,这是我第一次测试通知服务时用 python 编写的一些代码。我喜欢它,因为它非常简单,并且在测试过程中运行良好。

      import socket, ssl, json, struct
      
      # device token returned when the iPhone application
      # registers to receive alerts
      
      deviceToken = 'XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX' 
      
      thePayLoad = {
           'aps': {
                'alert':'Oh no! Server\'s Down!',
                'sound':'k1DiveAlarm.caf',
                'badge':42,
                },
           'test_data': { 'foo': 'bar' },
           }
      
      # Certificate issued by apple and converted to .pem format with openSSL
      # Per Apple's Push Notification Guide (end of chapter 3), first export the cert in p12 format
      # openssl pkcs12 -in cert.p12 -out cert.pem -nodes 
      #   when prompted "Enter Import Password:" hit return
      #
      theCertfile = 'cert.pem'
      # 
      theHost = ( 'gateway.sandbox.push.apple.com', 2195 )
      
      # 
      data = json.dumps( thePayLoad )
      
      # Clear out spaces in the device token and convert to hex
      deviceToken = deviceToken.replace(' ','')
      byteToken = bytes.fromhex( deviceToken ) # Python 3
      # byteToken = deviceToken.decode('hex') # Python 2
      
      theFormat = '!BH32sH%ds' % len(data)
      theNotification = struct.pack( theFormat, 0, 32, byteToken, len(data), data )
      
      # Create our connection using the certfile saved locally
      ssl_sock = ssl.wrap_socket( socket.socket( socket.AF_INET, socket.SOCK_STREAM ), certfile = theCertfile )
      ssl_sock.connect( theHost )
      
      # Write out our data
      ssl_sock.write( theNotification )
      
      # Close the connection -- apple would prefer that we keep
      # a connection open and push data as needed.
      ssl_sock.close()
      

      还有一个名为 apn_on_rails 的 rails gem,如果您正在开发一个 rails 应用程序,它似乎工作得很好,我今天才看到它并且能够从控制台发送通知。

      在 iPhone 端,您只需调用以下命令即可注册所有类型的通知:

      [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
      

      要接收设备令牌,您需要实现以下委托方法:

      - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
      
      - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
      

      在测试期间,您可以使用 NSLog 将 deviceToken 踢到控制台,然后将其粘贴到上面的 python 脚本中,在生产中您显然需要设置一些方法来将令牌获取到您的服务器。

      此外,在生产环境中,您需要查询 Apple 的反馈服务并从删除您的应用的用户那里删除设备令牌。

      【讨论】:

      • 在下面查看 Simon 的答案 - 他将 Python 代码封装在一个不错的库中,您可以在这里找到:github.com/simonwhitaker/PyAPNs
      • 警告 - 此代码适用于协议的版本 0。 Apple 现在升级到第 2 版。
      • 自从写下这个答案后,我几乎完全搬到了 Urban Airship 来提供推送通知服务。我听说过一些对helios.io 的好评,但我自己从未使用过。
      • @jessecurry 非常感谢,另外两个问题,使用上面的代码有没有办法在不循环的情况下向我的所有用户发送通知?有没有在python服务器端实现飞艇的分步教程,你能分享你的代码吗?
      • 行:theNotification = struct.pack(theFormat, 0, 32, byteToken, len(data), data) 出错:struct.error: argument for 's' must be a bytes object
      【解决方案4】:

      这是一个经过测试的 php5 版本的 jessecurry 的测试脚本。 它使用'enhanced message format',并试图捕捉和显示来自苹果的错误。这可能表明您的消息有什么问题。

      // Settings
      $deviceToken = 'xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx';
      $apnsCert = 'apns-dev.pem';
      $apnsHost = 'gateway.sandbox.push.apple.com';
      $apnsPort = 2195;
      
      // Prepare payload
      $payload = 
      array(
          'aps' => array(
              'alert' => 'Hi, this is an alert!',
              'badge' => 8
          )
      );
      $payload = json_encode($payload);
      print($payload . "\n");
      
      // Connect to Apple Push Notification server
      $streamContext = stream_context_create();
      stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
      $apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);
      if (!$apns) {
          die('Error creating ssl socket');
      }
      // Don't block on reading from the socket
      stream_set_blocking ($apns, 0);
      
      // Send payload in enhanced message format ( http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW1 )
      $apnsMessage = 
          // Command "1"
          chr(1)
          // Identifier "88"
          . pack('N', 88)
          // Expiry "tomorrow"
          . pack('N', time() + 86400)
          // Token length
          . chr(0) . chr(32) 
          // Device token
          . pack('H*', str_replace(' ', '', $deviceToken)) 
          // Payload length
          . chr(0) . chr(strlen($payload)) 
          // Actual payload
          . $payload . $payload;
      fwrite($apns, $apnsMessage);
      
      // Pause for half a second to check if there were any errors during the last seconds of sending.
      usleep(500000); 
      
      checkAppleErrorResponse($apns);
      
      // Close connection -- apple would prefer that we keep
      // a connection open and push data as needed.
      fclose($apns);
      
      function checkAppleErrorResponse($apns)
      {
          $responseBinary = fread($apns, 6);
          if ($responseBinary !== false && strlen($responseBinary) == 6)
          {
              print(
                  "\n"
                  .'Error message recieved from Apple.'."\n"
                  .'For the meaning, refer to: "Provider Communication with Apple Push Notification Service"'."\n"
              );
              $response = unpack('Ccommand/Cstatus_code/Nidentifier', $responseBinary);
              var_dump($response);
          }
      }
      

      【讨论】:

        【解决方案5】:

        如果有帮助,我编写了一个 Python 库 PyAPNs,用于与服务器端的推送通知服务进行交互:

        http://github.com/simonwhitaker/PyAPNs

        【讨论】:

          【解决方案6】:

          我知道那晚了,但你应该看到MonoPush 项目。似乎他们将提供一种新的推送集成方式以及详细的统计信息,包括地图上的统计信息。

          【讨论】:

            【解决方案7】:

            一个好的起点是Urban Airship。您可以设置一个免费的基本帐户,该帐户将完成向 Apple 服务器发送推送通知的所有服务器端工作。他们还很好地引导您完成了让您的应用程序与他们的服务一起工作所需的所有步骤,并提供了出色的示例代码,展示了如何为您的应用程序注册通知。

            除了成为他们服务的快乐用户之外,我与他们没有其他任何关系。

            【讨论】:

            • 我目前也在走这条路线,因为大多数共享主机不允许连接到 Apple 的自定义端口以进行推送通知。我记得之前看到过一个用于 Google App Engine 的 Python 程序,它向 Urban Airship 发送 REST 请求(对基于 cron 的通知很有用),但目前我似乎找不到它。如果你们偶然发现它,请告诉我。谢谢!
            • 是的,他们的服务很好。他们已经扩展到真正的存储和转发服务,称为 AirMail,它可以将大部分工作从后端转移出去——它现在需要做的就是将带有嵌入式 HTML 的 JSON 发送到 Urban Airship 服务器;他们负责发送通知并在请求时提供 HTML。
            • 嘿,你能帮我在我的 iPhone 应用程序中实现 Urban Airship API 吗?看看我遇到了什么问题:stackoverflow.com/questions/5634125/… 我希望你一定有一些解决方案。谢谢
            【解决方案8】:

            http://blog.boxedice.com/2009/07/10/how-to-build-an-apple-push-notification-provider-server-tutorial/

            这对我使用 PHP 在 linux 服务器上制作提供商端代码帮助很大。

            【讨论】:

            • 请注意:大多数共享主机没有针对 APNS 开放的端口。因此,如果您想走这条路,您可能需要至少将其托管在 VPS 中。
            【解决方案9】:

            在 iPhone 端写的代码真的不多。您需要获取 iPhone 或 iPod Touch 的唯一令牌,然后将该令牌中继到您的服务器。获取令牌需要调用 UIApplication 但没有预定义的方法可以将其发送到您的服务器。我的一个应用程序对将令牌放入数据库的 PHP 脚本执行 HTTP POST。

            如果您对证书的配置和设置等感兴趣,可以查看 Apple Push Notification Service Programming Guide。

            【讨论】:

            • Ben,是的,从文档中看起来并不复杂,我也很肯定我会制定配置(还没有看过,但是......)很高兴有一个如何设置的分步示例。
            【解决方案10】:

            看iPhone开发中心的论坛,据说有很多服务器端代码的例子可以和苹果的推送服务器对话。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-11-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多