Apple Push Notification with Java Spring Framework

June 02, 2016

I am implementing a Java Spring Framework server which sends an Apple Push Notification to an iPhone using Swift. Here are the things you will need:

1. Account setup

Assume you already have an Apple developer account with certificates, login and go to the tab Identifiers and click “+” to add a new one. Fill in the prefix and suffix, then remember to check the box “Push Notifications

1  PIcbWEHzdGvg9BL4MiEMkw 1  xetPx7T01Kw9vOsUKi6tmw

Then select Edit, and scroll to the Push Notifications section, you will see the “Configurable” orange indicators. Create and download the Development SSL certificate using your CSR file. Double click to run and add to your key chain.

1  JucgUrB7Bi4  QcxUbqvdWA

Open Keychain Access, find the certificate and export it as .p2 file. You will be prompt to enter a password, which better not to leave it blank. Otherwise, the Java Spring app may not be able to parse an empty string. Save this file, which will be used in later steps.


2. Xcode setup

Create a new Xcode project, such as a Single View Application. In the Capabilities tab, enable ‘Push Notifications’ with your Apple ID accounts login.

1  p3Kk5TUripw19flWwOSeSQ

In the AppDelegate.swift, add a method to create an instance of settings, which get the user’s permission with a prompt when the app launches:

func registerForPushNotifications(application: UIApplication) { let notificationSettings = UIUserNotificationSettings( forTypes: [.Badge, .Sound, .Alert], categories: nil) application.registerUserNotificationSettings(notificationSettings) }

Invoke it when the finished launching:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. registerForPushNotifications(application) return true }

In the same AppDelegate.swift file, add the method below, which handles when a user accepts or declines the permissions.

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { if notificationSettings.types != .None { application.registerForRemoteNotifications() } }

Add the method below to handle if the registration is successful:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { let tokenChars = UnsafePointer(deviceToken.bytes) var tokenString = “”

for i in 0..<deviceToken.length { tokenString += String(format: “%02.2hhx”, arguments:[tokenChars[i]]) }

print(“Device Token:”, tokenString) }

Also for failure case of the registration:

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) { print(“Failed to register:”, error) }

You can now try and run the app. Notice that you will need a physical device, instead of a simulator to test it out. If things go well, you should see the device token in the console. Record this for later use.

1  Ve8hJNaqrul2EoVVcmbRnA

3. Java Spring Server setup

Create a Java spring framework server using your favourite IDE, like NetBeans or Intellij. In this example, we are using the maven build, with a pom.xml file like this:

<project xmlns=”” xmlns:xsi=”” xsi:schemaLocation=”“> 4.0.0

com.victorleungtw push-notification 0.0.1-SNAPSHOT jar

push-notification Push Notifcation

org.springframework.boot spring-boot-starter-parent 1.3.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter-data-rest org.springframework.boot spring-boot-starter-test test org.springframework.restdocs spring-restdocs-mockmvc test org.springframework.boot spring-boot-maven-plugin

Then we utilize the notnoop library from Maven Repository. Add this dependency to the pom.xml

com.notnoop.apns apns 1.0.0.Beta6

When the server started, it would look for the main, with example below:

package com.victorleungtw;

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication public class PushNotificationApplication {

public static void main(String[] args) {, args); } }

As a simple demo, we will create a

package com.victorleungtw;

import java.util.Map; import java.util.Date;

import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;

import com.notnoop.apns.APNS; import com.notnoop.apns.ApnsService;

/** * * @author victorleungtw */ @RestController public class NotificationController { private static final String template = “Hello, %s!”; private final AtomicLong counter = new AtomicLong(); ApnsService service = null;

@RequestMapping(“/notification”) public Notification notification(@RequestParam(value=”name”, defaultValue=”World”) String name) {

System.out.println(“Sending an iOS push notification…”);

ApnsService service = APNS.newService() .withCert(“XXX.p12”, “YOUR_PASSWORD”) .withSandboxDestination() .build();

String payload = APNS.newPayload() .alertBody(“Can’t be simpler than this!”) .alertTitle(“test alert title”).build();

String token = “b8f3b2513caa…”;

System.out.println(“payload: “+payload);

service.push(token, payload);

System.out.println(“The message has been hopefully sent…”);

return new Notification(counter.incrementAndGet(), String.format(template, name)); } }

Replace “XXX.p12”, “YOUR_PASSWORD” and “b8f3b2513caa…..” with your actual .p12 file path, password and the device token respectively. If you are not sure about the file path, you can put the .p12 file at the same level as your /src folder, i.e. the root of the project folder. That’s it. Run the following commands:

mvn install

And start the server:

mvn spring-boot:run

Open your browser, once you hit the route http://localhost:8080/notification, you should be able to receive a notification!

1  hatM2Cf5  WwhHvMvzxQoqA

Let me know if you have any questions :)

Written by Victor Leung who is a keen traveller to see every country in the world, passionate about cutting edge technologies. Follow me on Twitter