Products
chatkit_full-logo

Extensible API for in-app chat

channels_full-logo

Build scalable realtime features

beams_full-logo

Programmatic push notifications

Developers

Docs

Read the docs to learn how to use our products

Tutorials

Explore our tutorials to build apps with Pusher products

Support

Reach out to our support team for help and advice

Sign in
Sign up

Send push notifications to an iOS app with Java and AWS Lambda

  • Christopher Batin
June 12th, 2019
You will need Eclipse IDE for Java, the AWS Toolkit for Eclipse, and Xcode 10+

Introduction

Pusher Beams allows you to customize push notifications you send to your devices via a server. However it can be expensive to run a server 24 hours a day 7 days a week and we may only need to send notifications every so often. This is where AWS Lambda can help. Lambda functions are serverless and work on a pay as you go model (with a generous free tier). This means that you only pay for when you use the function. We’re going to explore how we can setup Pusher Beams on an iOS client using an AWS Lambda function running Java to trigger the notifications.

Prerequisites

  • A free AWS account. You can create one here.
  • A free Pusher account. You can create one here.
  • Eclipse IDE for Java Developers installed on your machine. Install instructions here.
  • AWS Toolkit for Eclipse installed and setup. Follow the instructions here.
  • Xcode 10+
  • MacOS
  • An iOS device for testing notifications.
  • An understanding of iOS development and Xcode environment.
  • Cocoapods - Install instructions here.

Create your Lambda function

Creating a Pusher Beams instance

Login or create an account to access your dashboard here. Create a new Pusher Beams instance using the dashboard.

Complete step one of the iOS setup guide, by providing your APNS key and team ID and clicking Continue. We will pick up the remainder later on in this tutorial. Press the X to exit the setup guide and you will be returned to your dashboard for that instance. Scroll to the bottom of the page and you will find your Pusher Beams instance ID and secret key, make note of these you will need them later.

Writing our function

Open your Eclipse IDE and press CMD + N this will open the new project wizard. Expand the AWS folder (make sure you have the AWS Toolkit installed if you don’t see this) and select AWS Lambda Java Project and click Next.

In the next window provide a Project name, Group ID, Artifact ID and Class Name. You may leave these as the default if you wish. For the Input Type, choose Custom, to complete the set up select Finish.

Once the project has finished setting up open the pom.xml. Add the following within your dependencies:

    // pom.xml
    <dependencies>
      ...
      <dependency>
          <groupId>com.pusher</groupId>
          <artifactId>push-notifications-server-java</artifactId>
          <version>1.1.0</version>
      </dependency>
      ...
    </dependencies>

Create a new file in the lambda package called RequestClass.java. Within this file add the following:

    // src/main/java/RequestClass.java
    package com.amazonaws.lambda.demo;

    public class RequestClass {
            String title;
            String message;

            public String getTitle() {
                    return title;
            }

            public void setTitle(String title) {
                    this.title = title;
            }

            public String getMessage() {
                    return message;
            }

            public void setMessage(String message) {
                    this.message = message;
            }

            public RequestClass(String title, String message) {
                    this.title = title;
                    this.message = message;
            }

            public RequestClass() {
            }
    }

This code will be used by our Lambda function in order to parse the data we will pass in to the function to create our push message. Next open your LambdaFunctionHandler.java and replace the contents with:

    // src/main/java/RequestClass.java
    package com.amazonaws.lambda.demo;

    import java.util.List;
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    import com.amazonaws.services.lambda.runtime.Context;
    import com.amazonaws.services.lambda.runtime.RequestHandler;
    import com.pusher.pushnotifications.PushNotifications;

    public class LambdaFunctionHandler implements RequestHandler<RequestClass, String> {

        @Override
        public String handleRequest(RequestClass request, Context context) {
            String instanceId = "YOUR_INSTANCE_ID";
            String secretKey = "YOUR_SECRET_KEY";

            PushNotifications beamsClient = new PushNotifications(instanceId, secretKey);
            List<String> interests = Arrays.asList("hello");

            Map<String, Map> publishRequest = new HashMap();
            Map<String, String> alertMessage= new HashMap();
            alertMessage.put("title", request.title);
            alertMessage.put("body", request.message);

            Map<String, Map> alert = new HashMap();
            alert.put("alert", alertMessage);

            Map<String, Map> aps = new HashMap();
            aps.put("aps", alert);
            publishRequest.put("apns", aps);

            try {
              beamsClient.publishToInterests(interests, publishRequest);
              return "Push sent!";
            } catch (IOException e) {
              e.printStackTrace();
              return "Push failed!";
            } catch (InterruptedException e) {
              e.printStackTrace();
              return "Push failed!";
            } catch (URISyntaxException e) {
              e.printStackTrace();
              return "Push failed!";
            }

        }
    }

This code will be used by our Lambda function later on to publish notifications to devices that are registered for the hello interest. We use the request.title and request.message to form part of the APNS notification. We’ll look at this in more detail when we come to test our integration. Remember to replace YOUR_INSTANCE_ID and YOUR_SECRET_KEY with the credentials from your Pusher Beams console.

Deploy your code

Right click in the eclipse editor select AWS Lambda → Upload function to AWS Lambda.

On the next screen select a IAM role if you have one. If you don’t use the Create button to make a new one and call it “lambda_basic_execution”. Next we would need to create a bucket on the AWS console here if we don’t already have one. Make sure that there are permissions to the root user. And lastly but most importantly make sure that the user created initially has all of the permissions required - AmazonS3FullAcces. Leave everything else the same and click Finish to upload your code to AWS Lambda.

Note: Always make sure the bucket region matches the Lambda target region.

Create your iOS application

Now that we have created our Lambda function, we need to have a user that has actually registered for notifications and signed up for the hello interest so we can test out our implementation. We’re going to create a very basic app that doesn’t actually show anything to the user except for the notification on the lock screen.

Project setup

Create a new Single View App using Xcode and name it something like LambdaPush. Once the project is created we need to install the Beams SDK. Open the terminal and go to the working directory of the newly created project and run the following command.

    $ pod init

Open the newly created Podfile and add the following pod:

    pod 'PushNotifications'

In the terminal run:

    $ pod install

Make sure you close your Xcode project and reopen the newly created Xcode Workspace before continuing. Within your project capabilities make sure you have switched on the Push Notifications capability. Also turn on the Background Modes capability and tick the box for Remote Notifications.

Open your AppDelegate.swift file and replace its contents with the following. Remembering to replace the instance ID with your own.

    // AppDelegate.swift
    import UIKit
    import PushNotifications

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
        let pushNotifications = PushNotifications.shared

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            self.pushNotifications.start(instanceId: "YOUR_INSTANCE_ID")
            self.pushNotifications.registerForRemoteNotifications()
            try? self.pushNotifications.subscribe(interest: "hello")

            return true
        }

        func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            self.pushNotifications.registerDeviceToken(deviceToken)
        }

        func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            self.pushNotifications.handleNotification(userInfo: userInfo)
        }
    }

You can now run the application on your iOS device and accept to receive notifications. The SDK will then manage registering our interest in hello. Remember to replace YOUR_INSTANCE_ID with your instance ID credential from your Pusher Beams console.

Testing our implementation

Return to your Lambda function code in the Eclipse IDE. Right-click and select AWS Lambda → Run function on AWS Lambda. A dialog box will appear, make sure your lambda function is selected from the dropdown list and that the Enter the JSON input for your function radio button is selected. In text field provided add the following:

    {"title": "hello", "message": "Just a friendly hello"}  

Notice how our keys in the JSON object are title and message. These are the event keys we were using in our code to provide the title and body for the push notification.

If everything has worked as expected you should receive a push to your device and a similar log output from your Lambda console.

Note: You can also test your integration directly from the AWS Lambda console. A function will have been created there for you.

Conclusion

We’ve learnt how to create an AWS Lambda function using Java that can publish a push notification using Pusher Beams to an iOS device. The source code for this tutorial can be found here.

Clone the project repository
  • Amazon Web Services
  • Beams
  • iOS
  • Java
  • Beams

Products

  • Channels
  • Chatkit
  • Beams

© 2019 Pusher Ltd. All rights reserved.

Pusher Limited is a company registered in England and Wales (No. 07489873) whose registered office is at 160 Old Street, London, EC1V 9BW.