Опыт отправки Apple Push Notification чере SNS сервис от Amazon и немного полезного кода

от автора

Теплым летним вечером, в процессе разработки очередного преложения для iOS, у меня совпало два фактора — возникла необходимость реализации Apple Push Notification (APN) и желание попробовать что-то совсем новое для меня. Идти проторенной дорогой через один из множества сервисов, предлагающих отправку APN не хотелось.

Для изобретения велосипеда был вабран Amazon Simple Notification Service (Amazon SNS). Amazon SNS — это сервис, который позволяет вам отправлять сообщения-нотификации, посредством разнообразных механизмов (APN, GCM, e-mail, SMS и т.д.).

О том, как это работает и более подробную информацию можно прочитать в документации Amazon. Я расскажу совсем немного, чтобы определиться с дальнейшей терменологией. У SNS есть два типа клиентов — публикаторы (publishers) и подписчики (subscribers). Публикаторы с подписчиками асинхрнно обмениваются сообщениями (messages), которые доставляются подписчикам, посредствам разнообразных механизмов. Для отправки груповых сообщений подписчики могут быть сгруппированы по темам (topics). Тогда все подписчики, подписанные на тему, получат сообщение в эту тему отправленное.

Картинка из документации Amazon:
image

Поскольку тема данной статьи — работа с сервисом SNS из iOS, подробно на бекенде останавливаться не будем. Скажу несколько предложений.
В рамках изобретения велосипеда бекенд был написан с использованием следующих технологий:

  • Java 1.8;
  • Spring Boot 1.2.4;
  • Maven 3.3;
  • AWS SDK for Java 1.10.1.

Я являюсь програмистом на Objective C/Swift, поэтому все это добро, включая Java, я в этом проекте использовал можно сказать впервые. Проект PushSnsSender выложил на GitHub. Во-первых, может кому-нибудь пригодится; а во-вторых, был бы очень рад push-реквестам.

Данный код поднимает веб-сервис, который на ваш POST-запрос вида:

{"topic": "arn:aws:sns:YOUR-TOPIC", "message": "Hooray!", "badge": 0, "sound": "bingbong.aiff", "isDebug": false }

Отправит APN “Hooray!” на SNS-тему “YOUR-TOPIC”.

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

Перед тем как приступить к программированию, в консоли AWS нужно выполнить следующие действия:

  • активация сервиса AWS SNS;
  • активация сервиса AWS Cognito;
  • создание Platform Application в сервисе SNS и привязка ключей Apple для работы с APN;
  • создание новой темы для сервиса SNS;
  • создание Identity Pool и привязанной к нему роли для сервиса Cognito.

Я не буду описывать перечисленные выше шаги, чтобы не повторять множество уже написанных статей. Кроме того, документация Amazon по каждому сервису действительно очень подробна и хороша — разобраться не составляет труда. Приведу несколько скриншотов для общего представления.

Окно создания Platform Application:
image

Окно создания новой темы:
image

Окно создания нового Identity Pool:
image

Немного задержимся на сервисе Cognito. Что это и зачем он нужен?

Как вы понимаете, с вашим уютным AWS не должено быть разрешено работать кому попало. За строгую авторизацию в AWS отвечает сервис Identity and Access Management, который каждому пользователю выдает ключи авторизации. Ключи авторизации, состоящие из Access Key Id и Secret Access Key — очень интимная штука, попавшая в неправильные руки может причинить вашему аккаунту AWS и вашему кошельку много-много бед. Поэтому никогда и не прикаких обстоятельствах не садитись в машину к незнакомым дядям не отдавайте ключи AWS.

Вместе с этим ваше iOS приложение на телефонах пользователей должно как-то авторизовываться в AWS, чтобы подписаться на тему. Тут на помощь нам приходит сервис AWS Cognito — одной из функций которого является аутентификация пользователей и назначение им определенной роли. Работать с сервисом достаточно просто. После создания нового Identity Pool, сервис сам сгенерит вам код, который надо использовать в вашем iOS приложении.

Окно нового Identity Pool и сгенерированного кода:
image

Вводные операции закончены и наконец можно перейти к любимой части — написанию кода.
Для работы с сервисами Amazon из нашего iOS приложения нам потребуется AWS SDK for iOS, а точнее три компонента оттуда: AWSCore; AWSSNS и AWSCognito. Для установки воспользуемся любимым менеджером пакетов, например для CocoaPods это будет выглядить так:
pod 'AWSCore', '~> 2.2' pod 'AWSSNS', '~> 2.2' pod 'AWSCognito', '~> 2.2'

Настало время самого интересного — ответа на вопрос: “Как из нашего iOS приложения подписаться на тему SNS?” Документация Amazon предложит нам решение в виде регистрации отдельного устройство и отправки сообщения на него, что для массовой рассылки абсолютно не подходит. Поэтому после авторизации с помощью кода, сгенеренного сервисом Cognito, мы просто вызовим API сервиса SNS и подпишемся на тему вручную.
Код вызова приведен ниже:

- (void)subscribeToPushTopicWithDeviceToken:(NSData *)deviceToken  {          AWSSNS *sns = [AWSSNS defaultSNS];      AWSSNSCreatePlatformEndpointInput *endpointRequest = [AWSSNSCreatePlatformEndpointInput new];          //get some device's IDs     NSString *userDeviceName = [[UIDevice currentDevice] name];     NSString *userDevicePlatform = [[UIDevice currentDevice] model];          //get SNS settings      self.myPlatformApplicationArn = @"arn:aws:sns:us-east-1:XXXXXXXXXXXXX:app/APNS/XXXXXXXXXXXXX";     self.myTopicArn = @"arn:aws:sns:us-east-1:XXXXXXXXXXXXX:XXXXXXXXXXXXX";      endpointRequest.platformApplicationArn = self.myPlatformApplicationArn;     endpointRequest.token = [self deviceTokenAsString:deviceToken];     endpointRequest.customUserData = [NSString stringWithFormat:@"%@ - %@", userDevicePlatform, userDeviceName];      [[[sns createPlatformEndpoint:endpointRequest] continueWithSuccessBlock:^id(AWSTask *task) {          AWSSNSCreateEndpointResponse *response = task.result;          AWSSNSSubscribeInput *subscribeRequest = [AWSSNSSubscribeInput new];          subscribeRequest.endpoint = response.endpointArn;         subscribeRequest.protocols = @"application";         subscribeRequest.topicArn = self.myTopicArn;          return [sns subscribe:subscribeRequest];      }] continueWithBlock:^id(AWSTask *task) {          if (task.cancelled) {             NSLog(@"AWS SNS Task cancelled!");         }          else if (task.error) {             NSLog(@"%s file: %s line: %d - AWS SNS Error occurred: [%@]", __FUNCTION__, __FILE__, __LINE__, task.error);         }          else {             NSLog(@"AWS SNS Task Success.");         }          return nil;      }];      } 

Вот и все. После успешного запуска приложения в консоли AWS вы увидите одно авторизованное устройство в Identity Pool сервиса Cognito и ваше устройство в качестве подписчика на тему:

Экран с отоброжением устройства, подписанного на тему:
image

Обратите внимание на различие ключей Apple для работы с APN в среде разработки и продуктивной среде.

Файлы Objective C:

BGMAwsSnsProvider.h
BGMAwsSnsProvider.m

Спасибо за внимание. Надеюсь, данная статья съэкономила вам хоть сколько-нибудь времени и подтолкнула обратить внимание на такой замечательный сервис как Amazon SNS.

ссылка на оригинал статьи http://habrahabr.ru/post/269963/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *