Теплым летним вечером, в процессе разработки очередного приложения для 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:
Поскольку тема данной статьи — работа с сервисом SNS из iOS, подробно на бекенде останавливаться не будем. Скажу несколько предложений.
В рамках изобретения велосипеда бекенд был написан с использованием следующих технологий:
Я являюсь программистом на Objective C/Swift, поэтому все это добро, включая Java, я в этом проекте использовал можно сказать впервые. Проект PushSnsSender выложил на GitHub. Во-первых, может кому-нибудь пригодится; а во-вторых, был бы очень рад push-реквестам.
Данный код поднимает веб-сервис, который на ваш POST-запрос вида:
Отправит APN “Hooray!” на SNS-тему “YOUR-TOPIC”.
Как бы то ни было, не ради бекенда я затевал эту статью. Все дело в том, что механизм подписки на топик из iOS приложения несправедливо обойден вниманием в документации Amazon, а именно на нем я хочу остановиться. Возможно кому-то это сэкономит драгоценные часы времени.
Перед тем как приступить к программированию, в консоли AWS нужно выполнить следующие действия:
Я не буду описывать перечисленные выше шаги, чтобы не повторять множество уже написанных статей. Кроме того, документация Amazon по каждому сервису действительно очень подробна и хороша — разобраться не составляет труда. Приведу несколько скриншотов для общего представления.
Окно создания Platform Application:
Окно создания новой темы:
Окно создания нового Identity Pool:
Немного задержимся на сервисе Cognito. Что это и зачем он нужен?
Как вы понимаете, с вашим уютным AWS не должно быть разрешено работать кому попало. За строгую авторизацию в AWS отвечает сервис Identity and Access Management, который каждому пользователю выдает ключи авторизации. Ключи авторизации, состоящие из Access Key Id и Secret Access Key — очень интимная штука, которая при попадании в неправильные руки может причинить вашему аккаунту AWS и вашему кошельку много-много бед. Поэтому никогда и не при каких обстоятельствахне садитесь в машину к незнакомым дядям не отдавайте ключи AWS.
Вместе с этим ваше iOS приложение на телефонах пользователей должно как-то авторизовываться в AWS, чтобы подписаться на тему. Тут на помощь нам приходит сервис AWS Cognito — одной из функций которого является аутентификация пользователей и назначение им определенной роли. Работать с сервисом достаточно просто. После создания нового Identity Pool, сервис сам сгенерит вам код, который надо использовать в вашем iOS приложении.
Окно нового Identity Pool и сгенерированного кода:
Вводные операции закончены и наконец можно перейти к любимой части — написанию кода.
Для работы с сервисами Amazon из нашего iOS приложения нам потребуется AWS SDK for iOS, а точнее три компонента оттуда: AWSCore; AWSSNS и AWSCognito. Для установки воспользуемся любимым менеджером пакетов, например для CocoaPods это будет выглядеть так:
Настало время самого интересного — ответа на вопрос: “Как из нашего iOS приложения подписаться на тему SNS?” Документация Amazon предложит нам решение в виде регистрации отдельного устройство и отправки сообщения на него, что для массовой рассылки абсолютно не подходит. Поэтому после авторизации с помощью кода, сгенеренного сервисом Cognito, мы просто вызовим API сервиса SNS и подпишемся на тему вручную.
Код вызова приведен ниже:
Вот и все. После успешного запуска приложения в консоли AWS вы увидите одно авторизованное устройство в Identity Pool сервиса Cognito и ваше устройство в качестве подписчика на тему:
Экран с отоброжением устройства, подписанного на тему:
Обратите внимание на различие ключей Apple для работы с APN в среде разработки и продуктивной среде.
Файлы Objective C:
BGMAwsSnsProvider.h
BGMAwsSnsProvider.m
Спасибо за внимание. Надеюсь, данная статья сэкономила вам хоть сколько-нибудь времени и подтолкнула обратить внимание на такой замечательный сервис как Amazon SNS.
Для изобретения велосипеда был выбран Amazon Simple Notification Service (Amazon SNS). Amazon SNS — это сервис, который позволяет вам отправлять сообщения-нотификации, посредством разнообразных механизмов (APN, GCM, e-mail, SMS и т.д.).
О том, как это работает и более подробную информацию можно прочитать в документации Amazon. Я расскажу совсем немного, чтобы определиться с дальнейшей терминологией. У SNS есть два типа клиентов — публикаторы (publishers) и подписчики (subscribers). Публикаторы с подписчиками асинхронно обмениваются сообщениями (messages), которые доставляются подписчикам, посредством разнообразных механизмов. Для отправки групповых сообщений подписчики могут быть сгруппированы по темам (topics). Тогда все подписчики, подписанные на тему, получат сообщение в эту тему отправленное.
Картинка из документации Amazon:
Поскольку тема данной статьи — работа с сервисом 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:
Окно создания новой темы:
Окно создания нового Identity Pool:
Немного задержимся на сервисе Cognito. Что это и зачем он нужен?
Как вы понимаете, с вашим уютным AWS не должно быть разрешено работать кому попало. За строгую авторизацию в AWS отвечает сервис Identity and Access Management, который каждому пользователю выдает ключи авторизации. Ключи авторизации, состоящие из Access Key Id и Secret Access Key — очень интимная штука, которая при попадании в неправильные руки может причинить вашему аккаунту AWS и вашему кошельку много-много бед. Поэтому никогда и не при каких обстоятельствах
Вместе с этим ваше iOS приложение на телефонах пользователей должно как-то авторизовываться в AWS, чтобы подписаться на тему. Тут на помощь нам приходит сервис AWS Cognito — одной из функций которого является аутентификация пользователей и назначение им определенной роли. Работать с сервисом достаточно просто. После создания нового Identity Pool, сервис сам сгенерит вам код, который надо использовать в вашем iOS приложении.
Окно нового Identity Pool и сгенерированного кода:
Вводные операции закончены и наконец можно перейти к любимой части — написанию кода.
Для работы с сервисами 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 и ваше устройство в качестве подписчика на тему:
Экран с отоброжением устройства, подписанного на тему:
Обратите внимание на различие ключей Apple для работы с APN в среде разработки и продуктивной среде.
Файлы Objective C:
BGMAwsSnsProvider.h
BGMAwsSnsProvider.m
Спасибо за внимание. Надеюсь, данная статья сэкономила вам хоть сколько-нибудь времени и подтолкнула обратить внимание на такой замечательный сервис как Amazon SNS.
Комментарии (3)
bigMOTOR
02.11.2015 15:49InstaRobot Как же я просмотрел-то… Поправил. Спасибо!
InstaRobot
02.11.2015 15:52Под заголовком статьи иконка «гаечный ключ» у Вас должна быть. Чуть выше тегов и правее.
InstaRobot
В начале статьи, слово «преложения» поправьте плиз. Я не филолог, но статьи с Хабра очень быстро идут в индекс поисковых систем