Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending and receiving push notifications via AWS SNS

I've been trying to to create an app in order to send and receive push notifications via AWS SNS. I am new to the API and couldn't find a reliable tutorial. Here is the functions I've came up with in order to send and receive notifications:

func subscribe(deviceTokenString : String)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKey, secretKey: AWSSecretKey)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

    let sns = AWSSNS.defaultSNS()

    let subscribeInput = AWSSNSSubscribeInput()

    subscribeInput.topicArn = SNSTopicARN

    sns.subscribe(subscribeInput).continueWithBlock
    {
        (task) -> AnyObject! in
        if task.error != nil
        {
            print("Subscribed successfully")
            let confirmSubscription = AWSSNSConfirmSubscriptionInput()
            confirmSubscription.topicArn = SNSTopicARN
            confirmSubscription.token = deviceTokenString
            sns.confirmSubscription(confirmSubscription).continueWithBlock
            {
                (task) -> AnyObject! in
                if task.error != nil
                {
                    print("Confirmed subscription")
                    self.sendMessage()
                }
                else
                {
                    print("Subscription confirmation failed with error: \(task.error)")
                }
                return nil
            }
        }
        else
        {
            print("Error while subscribing: \(task.error)")
        }
        return nil
    }

}

func sendMessage()
{
    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    let dict = ["default": "Hello World!", "APNS_SANDBOX": "{\"aps\":{\"alert\": \"HELLO WORLD!\",\"sound\":\"default\", \"badge\":\"1\"} }"]

    do
    {
        let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)
        request.message = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
        request.topicArn = SNSTopicARN
        sns.publish(request).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                print("Error sending mesage: \(task.error)")
            }
            else
            {
                print("Success sending message")
            }
            return nil
        }
    }
    catch
    {
        print("Error on json serialization: \(error)")
    }

}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
    let deviceTokenString = "\(deviceToken)"
        .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString:"<>"))
        .stringByReplacingOccurrencesOfString(" ", withString: "")
    print("deviceTokenString: \(deviceTokenString)")
    subscribe(deviceTokenString)
}

Everything seems to work well, I get the "Subscribed successfully", "Confirmed subscription" and "Message sent" logs on the console, but application:didReceiveRemoteNotificationuserInfo: never gets called. What am I doing wrong?

like image 552
user26830 Avatar asked Jul 10 '15 07:07

user26830


People also ask

What type of notification mechanism does Amazon SNS use?

Amazon SNS delivers mobile push notifications through Amazon Device Messaging (ADM), Apple Push Notification Service (APNs), Baidu Cloud Push (Baidu), Firebase Cloud Messaging (FCM), Microsoft Push Notification Service for Windows Phone (MPNS), and Windows Push Notification Services (WNS).

How do I push a message to SNS?

Sign in to the Amazon SNS console . In the left navigation pane, choose Topics. On the Topics page, select a topic, and then choose Publish message. The console opens the Publish message to topic page.

Is SNS push based?

Amazon Simple Queue Service (SQS) and Amazon SNS are both messaging services within AWS, which provide different benefits for developers. Amazon SNS allows applications to send time-critical messages to multiple subscribers through a “push” mechanism, eliminating the need to periodically check or “poll” for updates.

Which port is being used by SNS to send the notification?

The Amazon SNS Topic external action has two output ports. The success port (✔) can send a message if the Amazon SNS topic is notified successfully. The failure port (x) can send a message if the notification fails.


1 Answers

I've figured out that I was missing some points. Here is the piece of code perfectly works.

func subscribe(token : String, completionHandler : ((NSError?) -> ())? = nil)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKeySend, secretKey: AWSSecretKeySend)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)

    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration

    let sns = AWSSNS.defaultSNS()
    let createPlatformEndpointInput = AWSSNSCreatePlatformEndpointInput()
    createPlatformEndpointInput.token = token
    createPlatformEndpointInput.platformApplicationArn = SNSPlatformApplicationArn

    sns.createPlatformEndpoint(createPlatformEndpointInput).continueWithBlock
    {
        (task) -> AnyObject! in
        if task.error != nil
        {
            print("Error creating platform endpoint: \(task.error)")
            completionHandler?(task.error)
            return nil
        }
        let result = task.result as! AWSSNSCreateEndpointResponse
        let subscribeInput = AWSSNSSubscribeInput()
        subscribeInput.topicArn = SNSTopicARN
        subscribeInput.endpoint = result.endpointArn
        print("Endpoint arn: \(result.endpointArn)")
        subscribeInput.protocols = "application"
        sns.subscribe(subscribeInput).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                completionHandler?(task.error)
                print("Error subscribing: \(task.error)")
                return nil
            }
            print("Subscribed succesfully")
            let subscriptionConfirmInput = AWSSNSConfirmSubscriptionInput()
            subscriptionConfirmInput.token = token
            subscriptionConfirmInput.topicArn = SNSTopicARN
            sns.confirmSubscription(subscriptionConfirmInput).continueWithBlock
            {
                (task) -> AnyObject! in
                if task.error != nil
                {
                    print("Confirmed subscription")
                }
                completionHandler?(task.error)
                return nil
            }
            return nil
        }
        return nil
    }
}

func sendMessage(message : String, type : String = "alert", sound : String = "default", badges : Int = 1, completionHandler : ((NSError?) -> ())? = nil)
{
    let credentialsProvider : AWSStaticCredentialsProvider = AWSStaticCredentialsProvider(accessKey: AWSAccessKeySend, secretKey: AWSSecretKeySend)
    let defaultServiceConfiguration : AWSServiceConfiguration = AWSServiceConfiguration(region: DefaultServiceRegionType, credentialsProvider: credentialsProvider)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = defaultServiceConfiguration


    let sns = AWSSNS.defaultSNS()
    let request = AWSSNSPublishInput()
    request.messageStructure = "json"

    let dict = ["default": message, "APNS_SANDBOX": "{\"aps\":{\"\(type)\": \"\(message)\",\"sound\":\"\(sound)\", \"badge\":\"\(badges)\"} }"]

    do
    {
        let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions.PrettyPrinted)
        request.message = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
        request.topicArn = SNSTopicARN

        sns.publish(request).continueWithBlock
        {
            (task) -> AnyObject! in
            if task.error != nil
            {
                print("Error sending mesage: \(task.error)")
            }
            else
            {
                print("Success sending message")
            }
            completionHandler?(task.error)
            return nil
        }
    }
    catch
    {
        print("Error on json serialization: \(error)")
    }

}
like image 69
user26830 Avatar answered Sep 29 '22 14:09

user26830