[UPD: 02.12.14] Apple Push Notifications (APNs) для php-serverside-разработчика или Как интегрировать и работать с уведомлениями от Apple

Fork me on GitHub

Я уже недавно затрагивал тему Apple Push Notifications в статье Apple Push Notifications (APNs) для php-serverside-разработчика или Кто виноват при ошибке unable to connect to ssl://gateway.push.apple.com:2195 (Permission denied)

На этот раз я расскажу о Apple Push Notifications в общем. О том, с чем мне пришлось столкнуться при интеграции уведомлений в php-сайт и как это все происходило.

Напомню, что Apple Push Notifications — это уведомления для пользователей, отправляемые вашим сервером (любым, который сможет открыть SSL-соединение и передать бинарные данные), и получаемые каким-то iPhone/iPod/iPad приложением.

Как правило уведомления эти используются для коротких сообщений (я использую не более 180 символов в кодировке utf-8), содержащих допустим поздравление с днем рождения, рекламу какого-то мероприятия, уведомление о том, что сервер упал, и т.п.

Схожего эффекта можно добиться и собственными силами приложения, если заставить его постоянно опрашивать ваш сервер. Но в таком случае это будут постоянные запросы, 90% из которых будут бессмысленны для данной задачи.

APNs же в свою очередь позволяет приложению не думать о уведомлениях. Более того, приложение даже не должно быть запущено (но должно быть установлено), чтобы получать Push Notifications. Ваш сервер будет общаться с серверами Apple. Apple будет собирать Push Notifications пачками или по одному и отправлять их на все устройства, на которые нужно.

 

Для того, чтобы использовать APNs вам понадобиться:

— iOS приложение, зарегистрированное для получения уведомлений (разрешение на получение кстати выдаст пользователь (а может и не выдаст ), когда после установки и первого запуска приложения ему будет выведен соответствующий диалог)

— работающий веб-сервер для приложения (у меня это LAMP) с возможностью открыть безопасный сокет на порты 2195 и 2196.

 

В моем случае iOS приложением занималась сторонняя команда. Поэтому за разработку, подключение и генерирование сертификатов отвечали они.

Если у вас такой же случай, то от iOS команды разработчиков вам понадобится сертификат Bla-bla_someCert.p12, как его получить они могут почитать допустим здесь.

В экспортированном файле .p12 мне прислали сразу и development сертификат, и privat key. Для использования на сервере все это добро нужно конвертировать в формат .pem . сделать это можно из практически любой linux-консоли:

openssl pkcs12 -in server_certificates_bundle_sandbox.p12 -out server_certificates_bundle_sandbox.pem -nodes -clcerts

Следующее, что вам понадобиться от iOS команды — чтобы они периодически отправляли из своего приложения к вам на сервер device_token. Это не тоже самое, что device_id. device_token — это уникальная комбинация для пары устройство/приложение. Считайте, что device_token — это своеобразные адрес, по которому ваше уведомление придет именно вашему пользователю и именно для вашего iOS приложения.

Обычно device_token выглядит так (иногда он бывает разбит пробелами):

	0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78

Этот токен вам нужно сохранить. В дальнейшем на его основе вы будете отсылать push notifications.

 

Кстати, мое серверное приложение было написано на php с помощью Codeigniter. Поэтому решение я искал под php немного специфическое под саму платформу CI. На тот момент таких специфических решений я не нашел, зато нашел несколько php библиотек:

APNs-php

php-apns

Apple-Push-Notification-Server

Я попробовал использовать APNs-php, но не сложилось. Я промучался полчаса с подключением и бросил. Было решено адаптировать Apple-Push-Notification-Server (c) 2010 Benjamin Ortuzar Seconde под Codeigniter

В процессе адаптации от множества файлов в родительской библиотеке, в моей остались только config-файл, и сама библиотека. Часть кода была переписана, т.к. меня не устраивала. В итоге получилась довольно неплохая, надеюсь простая и (проверено) рабочая библиотека для отправки Apple Push Notifications в Codeigniter под названием codeigniter-apns.

Она умеет работать в enhance-режиме с подробным выводом отладки, также заложены предпосылки, для отправки очереди сообщений. Она умеет отправлять произвольные данные. Она умеет проверять APNs feedback.

Пример использования:

function send_notifications()
{
    $this->load->library('apn');
    $this->apn->payloadMethod = 'enhance'; // включите этот метод для отладки
    $this->apn->connectToPush();

    // добавление собственных переменных в notification
    $this->apn->setData(array( 'someKey' => true ));

    $send_result = $this->apn->sendMessage($device_token, 'Тестовое уведомление #1 (TIME:'.date('H:i:s').')', /*badge*/ 2, /*sound*/ 'default'  );

    if($send_result)
        log_message('debug','Отправлено успешно');
    else
        log_message('error',$this->apn->error);


    $this->apn->disconnectPush();
}

// для получения идентификаторов устройств, на которых приложение больше не установлено
public function apn_feedback()
{
    $this->load->library('apn');

    $unactive = $this->apn->getFeedbackTokens();

    if (!count($unactive))
    {
        log_message('info','Feedback: No devices found. Stopping.');
        return false;
    }

    foreach($unactive as $u)
    {
        $devices_tokens[] = $u['devtoken'];
    }

    /*
    print_r($unactive) -> Array ( [0] => Array ( [timestamp] => 1340270617 [length] => 32 [devtoken] => 002bdf9985984f0b774e78f256eb6e6c6e5c576d3a0c8f1fd8ef9eb2c4499cb4 ) ) 
    */
}

 

Больше информации вы можете почерпнуть, если вы владеете английским в достаточной степени, а также имеете к этому желание, то милости прошу посетить статьи, которыми я пользовался для интеграции с APNs:

http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html

http://www.make-awesome.com/2010/10/hey-apple-your-push-notifications-api-sucks/

http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12

http://www.jailbreakiphone45.net/jailbreak-iphone-4/push-notification-apple.html

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

http://mobile.tutsplus.com/tutorials/iphone/iphone-sdk_apns/

 

На русском языке информация тоже есть, но ее мало. Толкового вспомнилось только с Хабра:

http://habrahabr.ru/post/130365/

 

И на закуску проблемы с которыми столкнулся я:

1) Самая большая и долго неразрешимая проблема была с ошибкой от APNs — Invalid Device Token. Я побывал с ней и на askdev.ru, и на hashcode.ru и конечно же на stackoverflow.com, но решилась эта проблема только, когда приложение наконец было установлено из AppStore. Причем разработчику iOS приложения уведомления приходили всегда.

Помните, эта ошибка может возникать только по следующим причинам:

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

2. токен не соответствует сертификату — т.е. если ваше приложение установленно не через AppStore, то вам нужно подключать development сертификат. Если установлено через AppStore — то production-сертификат. как правило первым делом тестируйте уведомления на устройстве человека, чей development сертификат вы используете. Затем включайте production сертификат, устанавливайте сборку через testFlight или Crashlitics

 

[UPD: 02.12.14]

Не так давно я узнал о утилитах для работы с APNs (и не только) из командной строки — http://nomad-cli.com/, обязательно попробуйте.

Полезно(1)Бесполезно(0)

7 Responses to “ [UPD: 02.12.14] Apple Push Notifications (APNs) для php-serverside-разработчика или Как интегрировать и работать с уведомлениями от Apple ”

  1. Вот есть еще нативное (и вроде как живое) раширение для PHP - php-apn http://libcapn.org/php-apn, http://pecl.php.net/package/apn

    Но вообще я использую для рассылки сообщений отдельный демон

    Полезно(0)Бесполезно(0)
    • Городецкий

      Городецкий

      Большую часть рассылки я тоже запускал отдельно, но по крону и с использованием той же библиотеки.
      За расширение спасибо, добавил в закладки.

      Полезно(0)Бесполезно(0)
      • А как с производительностью? не замеряли, например, сколько занимет отправка 1000 пушей по крону?

        Полезно(0)Бесполезно(0)
        • Игорь

          По крону запускать - не очень то лучшая идея. Лучше использовать AMQP протокол. https://github.com/ZhukV/AppleApnPush/tree/2.0/demo/queue

          Полезно(0)Бесполезно(0)
        • Городецкий

          Городецкий

          Увы, не замерял.

          Полезно(0)Бесполезно(0)
  2. Игорь

    При работе с пушами, лучшего пакета для пыхи пока не находил: https://github.com/ZhukV/AppleApnPush

    Полезно(0)Бесполезно(1)
Комментарии закрыты.