Пример кода Apple PNS (услуги push-уведомлений) - PullRequest
51 голосов
/ 27 июня 2009

Есть ли пример проекта, показывающий, как использовать APNS на IPhone и как его настроить? В настоящее время я смотрю на документацию, но было бы неплохо иметь какой-то рабочий код, чтобы выделить его и посмотреть, как все это работает вместе?

Кажется, я ничего не могу найти с помощью Google или в центре разработки iphone.

Ответы [ 10 ]

59 голосов
/ 28 сентября 2009

Самое плохое в настройке службы push-уведомлений - это подготовка. Основным камнем преткновения, с которым я столкнулся, было наличие сертификата и ключа в файле .cer, который вы загружаете с сайта Apple, я написал системную службу на 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()

Существует также rails gem, называемый apn_on_rails, который, кажется, работает очень хорошо, если вы разрабатываете приложение rails, я только сегодня видел его и смог отослать уведомления с консоли.

На iPhone вам нужно всего лишь позвонить, чтобы зарегистрироваться для всех типов уведомлений:

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

Для получения токена устройства вам необходимо реализовать следующие методы делегата:

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

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

Во время тестирования вы можете просто выкинуть deviceToken на консоль с помощью NSLog, а затем вставить его в скрипт python выше, при работе вам, очевидно, потребуется настроить какой-то метод для получения токена на ваши серверы.

Кроме того, в процессе работы вам потребуется запросить службу обратной связи Apple и удалить токены устройств у пользователей, которые удалили ваше приложение.

15 голосов
/ 20 декабря 2009

Хорошее место для начала - Urban Airship . Вы можете создать бесплатную базовую учетную запись, которая будет выполнять всю серверную работу по отправке push-уведомлений на серверы Apple. Они также отлично справляются со всеми этапами, необходимыми для работы приложения с их сервисом, и имеют отличный пример кода, который показывает, как зарегистрировать приложение для уведомлений.

У меня нет никаких других связей с ними, кроме как быть счастливым пользователем их услуг.

14 голосов
/ 28 августа 2010

На случай, если это поможет, я написал библиотеку Python PyAPN для взаимодействия со службой push-уведомлений на стороне сервера:

http://github.com/simonwhitaker/PyAPNs

12 голосов
/ 05 октября 2009

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

Этот мне очень помог с созданием кода на стороне провайдера на сервере Linux с PHP.

5 голосов
/ 27 июня 2009

Там действительно не так много кода, чтобы написать на стороне iPhone. Вам необходимо получить уникальный токен iPhone или iPod Touch, а затем передать его на ваш сервер. Для получения токена требуется вызов UIApplication, но не существует заранее определенного способа передачи этого на ваш сервер. Одно из моих приложений выполняет HTTP POST для PHP-скрипта, который помещает токен в базу данных.

Если вас интересует подготовка и настройка сертификатов и т. Д., Вы можете обратиться к Руководству по программированию службы push-уведомлений Apple.

4 голосов
/ 09 июля 2012

Я знаю, что это очень старый вопрос и получил много ответов, но я нашел урок по Рей Вендерлих очень полезным и хотел поделиться им с новичками APNS. Это очень полезно и очень легко понять.

3 голосов
/ 02 июня 2010

Я знаю, что было поздно, но вы должны увидеть проект MonoPush . Похоже, они предоставят новый способ интеграции push, а также подробную статистику, включая статистику по карте.

2 голосов
/ 27 июня 2009

Посмотрите на форумах в центре разработчиков iPhone, предположительно, есть много примеров серверного кода для общения с push-сервером Apple.

1 голос
/ 27 апреля 2013

Попробуйте проект NWPusher на GitHub. Он предоставляет приложения для OS X и iOS для отправки push-уведомлений вручную, или вы можете напрямую использовать входящую в комплект библиотеку Objective-C.

1 голос
/ 08 августа 2012

Вот проверенная php5-версия тестового скрипта jessecurry. Он использует расширенный формат сообщения и пытается отлавливать и отображать ошибки Apple. Это может указывать на то, что не так с вашими сообщениями.

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