Apple PNS(推送通知服务)示例代码

发布于 2024-07-25 19:15:56 字数 129 浏览 7 评论 0原文

是否有一个示例项目展示如何在 iPhone 上使用 APNS 以及如何进行设置? 我目前正在查看文档,但最好能有一些工作代码可以分开并看看它们是如何协同工作的?

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

Is there a sample project showing how to use APNS on the IPhone and how to set up things? I'm currently looking at the documentation but it would be nice to have some working code to pick apart and see how it all works together?

I can't seem to find anything using google or in the iphone dev center.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

套路撩心 2024-08-01 19:15:56

设置推送通知服务最糟糕的部分是配置。 我遇到的主要障碍是,您从 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 的反馈服务,并从删除您的应用程序的用户中删除设备令牌。

The worst part about setting up the push notification service is the provisioning. The major stumbling block that I came across was that there is a certificate and a key in the .cer file you download from Apple's site, I wrote a system service in C# that sent out notifications and the connections kept failing because I had exported the certificate and not the key.

I don't recall who originally wrote this, here is a little bit of code in python that helped me out when I was first testing the notification service. I like it because it is very simple and works well during testing.

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()

There's also a rails gem called apn_on_rails that seems to work pretty well if you're developing a rails application, I just saw it today and was able to send out notifications from the console.

On the iPhone side you'll just need to call the following to register for all types of notifications:

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

To receive the device token you'll need to implement the following delegate methods:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

During testing you can just kick the deviceToken to the console with NSLog, then paste it into the python script above, in production you'll obviously need to set up some method to get the token to your servers.

Also, in production you'll need to query Apple's feedback service and remove device tokens from users who removed your app.

沉溺在你眼里的海 2024-08-01 19:15:56

城市飞艇是一个不错的起点。 您可以设置一个免费的基本帐户,该帐户将完成向 Apple 服务器发送推送通知的所有服务器端工作。 他们还出色地引导您完成让您的应用程序与其服务配合使用所需的所有步骤,并提供出色的示例代码,展示如何注册您的应用程序以获取通知。

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

A good place to start is Urban Airship. You can set up a free basic account that will do all of the server-side work of sending push notifications to Apple's servers. They also do a great job of walking you through all of the steps needed to get your application working with their service, and have excellent sample code that shows how to register your application for notifications.

I have no other affiliation with them other than being a happy user of their service.

英雄似剑 2024-08-01 19:15:56

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

http://github.com/simonwhitaker/PyAPNs

In case it helps, I've written a Python library, PyAPNs, for interacting with the Push Notification Service on the server side:

http://github.com/simonwhitaker/PyAPNs

遗心遗梦遗幸福 2024-08-01 19:15:56

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

这对我在提供程序端代码方面的帮助很大带有 PHP 的 Linux 服务器。

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

This one helped me a lot with making provider side code on linux server with PHP.

污味仙女 2024-08-01 19:15:56

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

如果您对证书的配置和设置等感到好奇,您可以查看 Apple 推送通知服务编程指南。

There really isn't much code to write on the iPhone side. You need to get the unique token of the iPhone or iPod Touch and then relay that token to your server. Getting the token requires a call to UIApplication but there's no predefined way of getting that to your server. One of my apps performs an HTTP POST to a PHP script that puts the token into a database.

If you're curious about provisioning and the setup of the certificates, etc..., you might check out the Apple Push Notification Service Programming Guide.

抱猫软卧 2024-08-01 19:15:56

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

I know this is a very old question and has received many answers but I found the tutorial of Rey Wenderlich very useful and wanted to share it for APNS beginners. It is very useful and very easy to understand.

等风来 2024-08-01 19:15:56

我知道已经晚了,但您应该查看 MonoPush 项目。 看来他们将提供一种新的推送集成方式以及详细的统计数据,包括地图上的统计数据。

I know that was late, but you should see MonoPush project. It seems they will be provide a new way push integration as well as detailed statistics, including statistics over the map.

我很坚强 2024-08-01 19:15:56

看看 iPhone 开发中心的论坛,据说有很多服务器端代码的示例来与 Apple 的推送服务器对话。

Look in the forums in the iPhone dev center, supposedly there are a lot of examples of server side code to talk to Apple's push server.

萝莉病 2024-08-01 19:15:56

这是 jessecurry 测试脚本的经过测试的 php5 版本。
它使用 '增强消息格式',并尝试捕获并显示来自苹果的错误。 这可能会表明您的消息有什么问题。

// 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);
    }
}

Here's a tested php5 version of jessecurry's test-script.
It uses the 'enhanced message format', and tries to catch and display errors from apple. This might give an indication as to what's wrong with your messages.

// 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);
    }
}
别念他 2024-08-01 19:15:56

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

Try the NWPusher project on GitHub. It provides OS X and iOS apps to send push notifications manually, or you can use the included Objective-C library directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文