вівторок, 11 серпня 2015 р.

Передача уведомлений в iOS-устройства

Используя технологии push-уведомлений, серверные приложения могут передавать мультимедийные сообщения в приложения, установленные на устройствах iOS или Android, исключая проблемы и расходы, связанные с реализацией в мобильном приложении службы коротких сообщений (Short Message Service - SMS) или мультимедийных сообщений (Multimedia Messaging Service - MMS). Майкл Юань показывает, как обеспечить эту важную функцию в приложениях для iOS. Читатель познакомится также с Java-библиотекой с открытым исходным кодом, которая упрощает процесс рассылки уведомлений.

Справочная информация

SMS- и MMS-сообщения доставляются операторами мобильных сетей на конкретные устройства по их телефонным номерам. Разработчики серверных приложений, реализующих службы SMS/MMS, должны приложить большие усилия, чтобы взаимодействовать с закрытыми телекоммуникационными инфраструктурами — включая получение телефонных номеров. (Подробнее о разработке серверных приложений SMS/MMS см. в статье Как встроить в Web-приложение мобильные текстовые сообщения.) Сообщения SMS/MMS не "знают" о приложениях, установленных на устройстве получателя.

Популярность смартфонов, таких как iPhone и Android-устройства (и их Wi-Fi-собратья, такие как iPod Touch и iPad), вызвала потребность в современной инфраструктуре для передачи мобильных сообщений, которые доставляют мультимедиа-сообщения непосредственно в установленные на них приложения — а не по телефонным номерам — и более открыты и доступны, чем SMS/MMS.

Apple и Google построили инфраструктуры на базе Интернета, позволяющие доставлять сообщения из серверных приложений соответственно на iOS- и Android-устройства. Push-уведомления изначально предназначены для взаимодействия с приложениями, установленными на мобильных устройствах. Они позволяют передавать текст, файлы мультимедиа и специальные данные, такие как мелодии звонков и бейджи для отображения на значках приложения.

В этой статье объясняется, как технология push-уведомлений работает на платформе iOS и как включить ее в свои приложения. Чтобы получить максимальный эффект от статьи, нужно обладать некоторым опытом программирования на платформе iOS и Java.

Двусторонние сообщения

Одной из замечательных особенностей инфраструктуры SMS/MMS является то, что сервер приложений может получать и отвечать на сообщения, отправленные из телефонов. Push-сообщения, напротив, представляют собой односторонний тип связи: их можно только передавать из сервера приложений в устройства. Но это не столь уж важно. Просто вместо того, чтобы сказать пользователю: «Для получения информации отправьте сообщение XYZ на номер 12345», вы можете предложить ему: «Чтобы получать информацию, загрузите приложение XYZ». И приложения сами будут передавать нужную информацию прямо на ваш сервер, исключая потребность в отправке сообщений.

Основы push-технологии iOS

Для проверки подлинности push-запросов из iOS-приложения Apple использует цифровые сертификаты с открытым ключом, поэтому сначала необходимо создать ключи аутентификации и зарегистрировать их в Apple. Этот простой, но довольно длительный процесс мы рассмотрим в следующем разделе.

Затем необходимо определить каждое устройство, которое устанавливает приложение и будет получать push-уведомления для этого приложения. Последовательность такова:

  1. Диалоговое окно в iOS-приложении спрашивает разрешение пользователя на получение уведомлений.
  2. Если разрешение получено, iOS-приложение подключается к службе Apple Push Notification (APNs) за строкой уникального идентификатора для этого установленного на устройстве приложения. (Его можно представить как аналог телефонного номера получателя в традиционном сценарии обмена сообщениями).
  3. iOS-приложение передает идентификатор приложению на сервере.
  4. Когда серверному приложению нужно отправить push-сообщение, оно проверяет подлинность push-серверов Apple и использует идентификатор для указания получателя сообщения.
  5. Если устройство получателя находится в онлайне, оно принимает и обрабатывает сообщение. Если устройство недоступно, сообщение ставится в очередь и доставляется, как только устройство выйдет на связь.

APNs также позволяют серверу приложений периодически проверять список идентификаторов приложений. Это создает возможности для исключения идентификаторов тех пользователей, которые удалили приложение или изменили свой push-in статус.

Может показаться, что предстоит много работы, и так оно и есть. Вот почему существуют коммерческие службы посредников типа Urban Airship (см. далее).

Мы покажем, как зарегистрировать свое приложение, а затем углубимся в подробности разработки iOS-приложения push-уведомлений и его серверных компонентов с помощью Java-библиотеки с открытым исходным кодом.

Альтернатива своему собственному серверу: Urban Airship

Urban Airship — это служба, которая позволяет передавать push-сообщения без необходимости создавать свой собственный сервер (см. раздел Ресурсы). Вы загружаете свои секретные ключи в Urban Airship и используете его Web-консоль для рассылки push-сообщений своим пользователям. Urban Airship предоставляет SDK для iOS, который облегчает регистрацию приложением каждого подключенного устройства на сервере, так что эти устройства отображаются на консоли управления сообщениями. Служба Urban Airship упрощает работу, но может оказаться дорогостоящей — и все равно основы технологии push-уведомлений нужно знать.

Регистрация приложения

Чтобы зарегистрировать свое приложение для передачи push-уведомлений, необходимо сначала создать пару секретного/открытого ключей для проверки подлинности API-вызовов, обращенных к серверам APNs. На Mac это делается с помощью "Связки ключей" (KeyChain Access). Выберите Связка ключей > Ассистент сертификации > Запросить сертификат у бюро сертификации, чтобы создать файл запроса на оформление сертификата. Файл запроса содержит сгенерированную пару из открытого ключа и соответствующего секретного ключа, сохраненную в "Связке ключей". Не забудьте выбрать в диалоговом окне пункт Сохранить на диск, как показано на рисунке 1.

Рисунок 1. Создание пары ключей и запроса на оформление из программы "Связка ключей" на компьютере Mac
Создание пары ключей и запроса на оформление из программы Связка ключей на компьютере Mac

Далее, посетите портал управления профилями пользователей и доступом к приложениям Apple (см. раздел Ресурсы) и загрузите туда свой запрос, который будет связан с соответствующим профилем. Большинство приложений имеет отладочный профиль для разработки и рабочий профиль для App Store, так что вам, скорее всего, придется сгенерировать и загрузить два файла запроса. Отправив запрос на портал, вы получите цифровой сертификат для загрузки. Сертификат содержит открытый ключ, который теперь серверы APNs будут распознавать как связанный с данным приложением. На рисунке 2 показан пример.

Рисунок 2. Цифровой сертификат Apple
Цифровой сертификат Apple

Загрузите цифровой сертификат и дважды щелкните на загруженном файле. "Связка ключей" автоматически импортирует цифровой сертификат и свяжет его с секретным ключом, сгенерированным при создании запроса. На рисунке 3 показана пара открытого и секретного ключей в "Связке ключей".

Рисунок 3. Пара открытого и секретного ключей в "Связке ключей"
Пара открытого и секретного ключей в Связке ключей

Теперь можно экспортировать пару ключей в файл, используя формат Personal Information Exchange (p12). При создании файла p12 "Связка ключей" попросит назначить пароль для защиты секретного ключа. При желании можно использовать пустой пароль.

С этого момента все ваши API-запросы к push-серверам APNs будут шифроваться с помощью секретного ключа из файла p12 и снабжаться открытым ключом с цифровой подписью, чтобы гарантировать, что это действительно API-вызов от вас. Я продемонстрирую, как использовать ключи, ниже, когда буду описывать взаимодействие с серверами APNs. (При использовании Urban Airship вас попросят передать файл p12 вместе с паролем на сервер, чтобы он мог отправлять push-сообщения от вашего имени.)

Теперь, имея push-сертификаты, нужно перезагрузить и переустановить свои профили управления доступом — потому что они изменились и теперь поддерживают push-уведомления для приложения.

Запрос и сохранение маркера устройства

Ваше iOS-приложение должно запрашивать разрешение пользователя на получение уведомлений на устройства, на которых оно установлено. Как правило, это делается в уполномоченном приложении (application delegate) посредством простого API-вызова, как показано в листинге 1.

Листинг 1. Запрос разрешения пользователя
[[UIApplication sharedApplication]
    registerForRemoteNotificationTypes:
        (UIRemoteNotificationTypeBadge |
         UIRemoteNotificationTypeSound | 
         UIRemoteNotificationTypeAlert)];

Если пользователь дает разрешение, приложение автоматически обращается к серверу APNs за маркером устройства. Маркер позволяет APNs идентифицировать это конкретное приложение, установленное на данном конкретном устройстве, в качестве места назначения сообщения. Это автоматический процесс, происходящий в фоновом режиме. Для него не нужно писать никакого кода.

После ответа сервера APNs вызывается метод didRegisterForRemoteNotificationsWithDeviceToken в уполномоченном приложении с маркером устройства, передаваемом в качестве параметра вызова. Сохраните маркер устройства и загрузите его на свой сервер push-уведомления, как показано в листинге 2.

Листинг 2. Получение идентификатора и его загрузка на сервер
- (void)application:(UIApplication*)application
         didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {

    NSString *tokenStr = [deviceToken description];
    NSString *pushToken = [[[[tokenStr 
      stringByReplacingOccurrencesOfString:@"<" withString:@""] 
      stringByReplacingOccurrencesOfString:@">" withString:@""] 
      stringByReplacingOccurrencesOfString:@" " withString:@""] retain];

   // Сохранить маркер на сервере

   NSString *urlStr = [NSString stringWithFormat:@"https://%@/push_token", RINGFULDOMAIN];
    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];

   [req setHTTPMethod:@"POST"];
   [req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
   NSMutableData *postBody = [NSMutableData data];
   [postBody appendData:[[NSString stringWithFormat:@"username=%@", username] 
      dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[[NSString stringWithFormat:@"&token=%@", 
      pushToken] dataUsingEncoding:NSUTF8StringEncoding]];

   [req setHTTPBody:postBody];
   [[NSURLConnection alloc] initWithRequest:req delegate:nil];
}

В идеале маркер ассоциируется с некоторой информацией, которую указывает пользователь (например, имя пользователя в вашей системе), чтобы сервер "знал", кто отправил сообщение. (Это аналог связывания телефонного номера с именем абонента.) Если маркеры не связать с информацией, идентифицирующей пользователей, все равно можно отправлять сообщения на эти устройства, но нельзя настраивать их для каждого пользователя, потому что у вас есть только маркер целевого устройства.

Сервер должен сохранить маркер и связанную с ним идентификационную информацию в базе данных. В большинстве приложений они сохраняются в базе данных профилей пользователей.

Отправка push-сообщения

Чтобы отправить push-сообщение, сервер выполняет следующие действия.

  1. Находит список идентификаторов адресатов сообщения.
  2. Настраивает сообщение для каждого получателя на основе профиля пользователя получателя.
  3. Устанавливает связь с сервером обмена сообщениями APNs.

У сервера APNs сложный API Web-сервисов. К счастью, для Java-разработчиков существует библиотека с открытым исходным кодом JavaPNS, которая значительно упрощает работу с ним. В разделе Ресурсы приведены ссылки на загрузку и документацию JavaPNS.

Код, приведенный в листинге 3, показывает, как отправить SMS-подобное сообщение на устройство с помощью библиотеки JavaPNS.

Листинг 3. Отправка push-сообщения
String[] devices = {"token1", "token2};
List<PushedNotification> notifications
 = Push.alert("Hello World!", "keypair.p12", "password", false, devices);

Главные методы интерфейса библиотеки JavaPNS ― это статические методы класса Push. APNs позволяет вставлять в сообщение различный контент. Полный перечень поддерживаемых типов информации содержится в руководстве по push-сообщениями iOS (см. раздел Ресурсы). Класс Push предоставляет удобные методы для сообщений каждого типа и выполняет преобразование сообщения в формат JavaScript Object Notation (JSON), принимаемый серверами APNs. В листинге 3keypair.p12 ― это файл p12, экспортированный из "Связки ключей", а password — пароль доступа к файлу p12. Массив devices — это список маркеров устройств, полученный от iOS-приложения. Все эти устройства получат данное push-сообщение. Значение false параметра указывает на то, что сообщение должно быть отправлено на сервер разработки (sandbox) APNs, а не на рабочий сервер. (Напомним, что одна пара ключей p12 обычно создается для целей отладки, а другая ― для рабочего сервера.)

Возвращаемое значение вызова метода ― это список объектов PushedNotification, которые можно использовать для выяснения статуса push-доставки, как показано в листинге 4.

Листинг 4. Проверка статуса push-доставки
for (PushedNotification notification : notifications) {
    if (notification.isSuccessful()) {
        /* Apple приняла уведомление и должна доставить его */
    } else {
        String invalidToken = notification.getDevice().getToken();
        /* Добавить здесь код для удаления invalidToken из базы данных */
    }
}

Если объект уведомления говорит вам, что маркер определенного устройства больше не активен, — например, если пользователь удалил приложение из устройства или отключил уведомления в параметрах настройки приложения, — то нужно удалить маркер из базы данных, чтобы не отправлять больше сообщений в это устройство.

Еще один способ обновления списка маркеров активных устройств ― периодически сверять сервер приложений с серверами APNs. Листинг 5 демонстрирует, как запросить службу обратной связи APNs с помощью JavaPNS, чтобы получить список недействительных маркеров устройств от отладочного сервера APNs.

Листинг 5. Проверка для обновления списка действительных маркеров устройств
List<Device> inactiveDevices = Push.feedback("keypair.p12", "password", false);
/* Удалить неактивные устройства из списка устройств */

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

Дополнительные соображения

Push-уведомления нельзя проверить на эмуляторах iOS; для тестирования приложения его необходимо установить на реальном устройстве. Поскольку цифровой сертификат, используемый для проверки подлинности сообщения, связан с профилем управления доступом к данным приложения, в процессе разработки или распространения его нужно тестировать с отладочным сертификатом. После проверки приложения и его помещения в App Store нужно перейти на рабочий сертификат.

Кроме того, важно понимать, что настройка и отправка push-сообщений для большой базы пользователей ― это ресурсоемкая задача. Например, может потребоваться просматривать базу данных в миллион пользовательской каждые 5 секунд, чтобы выявить 10 пользователей, которым в данный момент необходимо отправить сообщение. Чтобы поддерживать частую рассылку уведомлений большому количеству пользователей, нужна тщательно спроектированная и спланированная инфраструктура со стороны сервера. И наоборот, отправка push-сообщения миллиону пользователей сразу создает интенсивный трафик, которым, возможно, лучше управлять через пул потоков, а не блокировать единственный поток. Библиотека JavaPNS предоставляет простой API, использующий пулы потоков для рассылки сообщений на большое количество устройств одновременно.

Заключение

Push-технология позволяет серверу приложений обойти операторов связи и отправлять сообщения непосредственно на приложения iOS-устройств через Интернет. Хотя реализация push-уведомлений не тривиальна — требуются SSL-сертификаты на стороне клиента для проверки подлинности на серверах Apple, — помощь посредников, таких как Urban Airship, или библиотеки JavaPNS может облегчить рассылку уведомлений. SMS и MMS занимают свое место и остаются более надежными, чем push-технология, зато реализовав службу push-сообщений, iOS-приложения можно сделать богаче и разнообразнее.

Ресурсы

Научиться

Получить продукты и технологии

  • JavaPNS: загрузить JAR JavaPNS.


Оригинал

Немає коментарів:

Дописати коментар

HyperComments for Blogger

comments powered by HyperComments