📜 ⬆️ ⬇️

The experience of sending Apple Push Notification via Amazon's SNS service and some useful code

On a warm summer evening, during the development of the next iOS application, I had two factors that coincided - it became necessary to implement Apple Push Notification (APN) and the desire to try something completely new for me. There was no wish to go the beaten path through one of the many services offering to send APN.

Amazon Simple Notification Service (Amazon SNS) was chosen for the invention of the bike. Amazon SNS is a service that allows you to send notification messages through a variety of mechanisms (APN, GCM, e-mail, SMS, etc.).

How it works and more information can be found in the Amazon documentation . I will tell quite a bit to determine further terminology. SNS has two types of clients - publishers and subscribers. Publishers with subscribers asynchronously exchange messages (messages) that are delivered to subscribers through a variety of mechanisms. For sending group messages subscribers can be grouped by topic (topics). Then all subscribers subscribed to the topic will receive a message on this topic sent.
')
Picture from Amazon documentation:
image

Since the topic of this article is working with the SNS service from iOS, we will not dwell on the backend in detail. I will say a few sentences.
In the framework of the invention of the bike, the backend was written using the following technologies:


I am an Objective C / Swift programmer, so all this stuff, including Java, I used for the first time in this project. The project PushSnsSender posted on GitHub . First, can someone come in handy; and secondly, I would be very happy with push requests.

This code raises the web service, which on your POST request of the form:

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


Will send APN “Hooray!” To the “YOUR-TOPIC” SNS topic.

Anyway, not for the sake of backend, I started this article. The thing is that the subscription mechanism for a topic from an iOS application is unfairly overlooked in the Amazon documentation, and I want to dwell on it. Perhaps it will save someone precious hours of time.

Before you begin programming, you need to do the following in the AWS console:


I will not describe the steps listed above in order 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 out. Here are some screenshots for a general presentation.

Window Create Platform Application:
image

New topic creation window:
image

New Identity Pool creation window:
image

We will linger a little on the Cognito service. What is it and why is it needed?

As you can imagine, your cozy AWS should not be allowed to work for anyone. Identity and Access Management is responsible for strict authorization in AWS, which issues authorization keys to each user. Authorization keys, consisting of Access Key Id and Secret Access Key, are very intimate things that, if they hit the wrong hands, can cause your AWS account and your wallet a lot of trouble. Therefore, never and under no circumstances get into a car to unfamiliar uncles, do not give AWS keys.

At the same time, your iOS application on users' phones must somehow log in to AWS in order to subscribe to the topic. This is where AWS Cognito comes to help us - one of the functions of which is to authenticate users and assign them a specific role. Work with the service is quite simple. After creating a new Identity Pool, the service itself will generate the code for you to use in your iOS application.

New Identity Pool and generated code window:
image

The introductory operations are completed and finally you can go to your favorite part - writing code.
To work with Amazon services from our iOS application, we need AWS SDK for iOS, or rather three components from there: AWSCore; AWSSNS and AWSCognito. To install, we will use our favorite package manager, for example, for CocoaPods it will look like this:
pod 'AWSCore', '~> 2.2'
pod 'AWSSNS', '~> 2.2'
pod 'AWSCognito', '~> 2.2'


The time has come for the most interesting thing - answering the question: “How can I subscribe to the SNS topic from our iOS application?” Amazon documentation will offer us a solution in the form of registering a separate device and sending a message to it that 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:

 - (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 and your device as a subscriber for the topic:

Screen with device mapping, signed on:
image

Note the difference between Apple keys for working with APNs in the development and production environments.

Objective C files:

BGMAwsSnsProvider.h
BGMAwsSnsProvider.m

Thanks for attention. I hope this article saved you some time and pushed to pay attention to such a wonderful service as Amazon SNS.

Source: https://habr.com/ru/post/269963/


All Articles