Experience sending Apple Push Notification via Amazon's SNS service and some useful code
On a warm summer evening, in the process of developing the next iOS application, two factors coincided - I had to implement Apple Push Notification (APN) and want to try something completely new for me. I did not want to go the beaten path through one of the many services offering sending APN.
Amazon Simple Notification Service (Amazon SNS) was chosen to reinvent the wheel. Amazon SNS is a service that allows you to send notification messages through a variety of mechanisms (APN, GCM, e-mail, SMS, etc.).
You can read more about how this works and more information in the Amazon documentation.. I will tell quite a bit to decide on further terminology. SNS has two types of clients - publishers and subscribers. Publishers with subscribers asynchronously exchange messages that are delivered to subscribers through a variety of mechanisms. To send group messages, subscribers can be grouped by topics. Then all subscribers who subscribe to the topic will receive a message in this thread sent.
Image from Amazon documentation:

Since the topic of this article is working with the SNS service from iOS, we won’t dwell on the backend. I will say a few suggestions.
As part of the invention of the bicycle, the backend was written using the following technologies:
I am an Objective C / Swift programmer, so all this stuff, including Java, I used in this project I can say for the first time. The project PushSnsSender posted on GitHub . Firstly, it might come in handy for someone; and secondly, I would be very pleased with push requests.
This code picks up a web service which, to your POST request of the form: Sends APN “Hooray!” To the SNS-theme “YOUR-TOPIC”. Be that as it may, it was not for the backend that I started this article. The thing is that the subscription mechanism for the topic from the iOS application is unfairly ignored in the Amazon documentation, and I want to dwell on it. Perhaps this will save someone precious hours of time. Before programming, in the AWS console, do the following:
I will not describe the steps listed above so as not to repeat the many articles already written. In addition, the Amazon documentation for each service is really very detailed and good - it’s easy to figure it out. I will give a few screenshots for a general presentation.
The window for creating the Platform Application:

The window for creating a new theme:

The window for creating a new Identity Pool: We linger a

bit on the Cognito service . What is it and why is it needed?
As you know, with your cozy AWS should not be allowed to work anyone. For strict authorization in AWS, the Identity and Access Management service is responsible, which issues authorization keys to each user. The authorization keys, consisting of Access Key Id and Secret Access Key, are a very intimate thing that, if falling into the wrong hands, can cause your AWS account and your wallet many, many troubles. Therefore, never, and under any circumstances,do not get in the car to unfamiliar uncles to give AWS keys.
At the same time, your iOS application on the phones of users must somehow log in to AWS in order to subscribe to the topic. Here the AWS Cognito service comes to the rescue - one of the functions of which is to authenticate users and assign them a specific role. Working with the service is quite simple. After creating a new Identity Pool, the service itself will generate a code for you to use in your iOS application.
The window of the new Identity Pool and generated code:

Introductory operations are completed and finally you can move on to your favorite part - writing code.
To work with Amazon services from our iOS application, we need the AWS SDK for iOS, or rather three components from there: AWSCore; AWSSNS and AWSCognito. To install, we’ll use our favorite package manager, for example, for CocoaPods it will look like this: The time has come for the most interesting one - the answer to the question: “How to subscribe to SNS from our iOS application?” Amazon documentation will offer us a solution in the form of registering a separate device and sending a message to him, which is absolutely not suitable for mass mailing. Therefore, after authorization using the code generated by the Cognito service, we simply call the SNS service API and subscribe to the topic manually. The call code is shown below:
That's all. After successfully launching the application in the AWS console, you will see one authorized device in the Cognito Identity Pool service and your device as a subscriber on the topic:
Screen with the display of a device signed on the topic:

Note the difference between Apple keys for working with APN in the development environment and productive environment.
Objective-C files:
BGMAwsSnsProvider.h
BGMAwsSnsProvider.m
Thank you for your attention. I hope this article saved you at least some time and prompted you to pay attention to such a wonderful service like Amazon SNS.
Amazon Simple Notification Service (Amazon SNS) was chosen to reinvent the wheel. Amazon SNS is a service that allows you to send notification messages through a variety of mechanisms (APN, GCM, e-mail, SMS, etc.).
You can read more about how this works and more information in the Amazon documentation.. I will tell quite a bit to decide on further terminology. SNS has two types of clients - publishers and subscribers. Publishers with subscribers asynchronously exchange messages that are delivered to subscribers through a variety of mechanisms. To send group messages, subscribers can be grouped by topics. Then all subscribers who subscribe to the topic will receive a message in this thread sent.
Image from Amazon documentation:

Since the topic of this article is working with the SNS service from iOS, we won’t dwell on the backend. I will say a few suggestions.
As part of the invention of the bicycle, the backend was written using the following technologies:
- Java 1.8
- Spring Boot 1.2.4;
- Maven 3.3;
- AWS SDK for Java 1.10.1.
I am an Objective C / Swift programmer, so all this stuff, including Java, I used in this project I can say for the first time. The project PushSnsSender posted on GitHub . Firstly, it might come in handy for someone; and secondly, I would be very pleased with push requests.
This code picks up a web service which, to your POST request of the form: Sends APN “Hooray!” To the SNS-theme “YOUR-TOPIC”. Be that as it may, it was not for the backend that I started this article. The thing is that the subscription mechanism for the topic from the iOS application is unfairly ignored in the Amazon documentation, and I want to dwell on it. Perhaps this will save someone precious hours of time. Before programming, in the AWS console, do the following:
{"topic": "arn:aws:sns:YOUR-TOPIC", "message": "Hooray!", "badge": 0, "sound": "bingbong.aiff", "isDebug": false }
- AWS SNS service activation
- AWS Cognito service activation
- Creation of a Platform Application in the SNS service and Apple key binding for working with APN;
- creating a new theme for the SNS service;
- Creating an Identity Pool and its associated role for the Cognito service.
I will not describe the steps listed above so as not to repeat the many articles already written. In addition, the Amazon documentation for each service is really very detailed and good - it’s easy to figure it out. I will give a few screenshots for a general presentation.
The window for creating the Platform Application:

The window for creating a new theme:

The window for creating a new Identity Pool: We linger a

bit on the Cognito service . What is it and why is it needed?
As you know, with your cozy AWS should not be allowed to work anyone. For strict authorization in AWS, the Identity and Access Management service is responsible, which issues authorization keys to each user. The authorization keys, consisting of Access Key Id and Secret Access Key, are a very intimate thing that, if falling into the wrong hands, can cause your AWS account and your wallet many, many troubles. Therefore, never, and under any circumstances,
At the same time, your iOS application on the phones of users must somehow log in to AWS in order to subscribe to the topic. Here the AWS Cognito service comes to the rescue - one of the functions of which is to authenticate users and assign them a specific role. Working with the service is quite simple. After creating a new Identity Pool, the service itself will generate a code for you to use in your iOS application.
The window of the new Identity Pool and generated code:

Introductory operations are completed and finally you can move on to your favorite part - writing code.
To work with Amazon services from our iOS application, we need the AWS SDK for iOS, or rather three components from there: AWSCore; AWSSNS and AWSCognito. To install, we’ll use our favorite package manager, for example, for CocoaPods it will look like this: The time has come for the most interesting one - the answer to the question: “How to subscribe to SNS from our iOS application?” Amazon documentation will offer us a solution in the form of registering a separate device and sending a message to him, which is absolutely not suitable for mass mailing. Therefore, after authorization using the code generated by the Cognito service, we simply call the SNS service API and subscribe to the topic manually. The call code is shown below:
pod 'AWSCore', '~> 2.2'
pod 'AWSSNS', '~> 2.2'
pod 'AWSCognito', '~> 2.2'
- (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;
}];
}
That's all. After successfully launching the application in the AWS console, you will see one authorized device in the Cognito Identity Pool service and your device as a subscriber on the topic:
Screen with the display of a device signed on the topic:

Note the difference between Apple keys for working with APN in the development environment and productive environment.
Objective-C files:
BGMAwsSnsProvider.h
BGMAwsSnsProvider.m
Thank you for your attention. I hope this article saved you at least some time and prompted you to pay attention to such a wonderful service like Amazon SNS.