Apple Push Notifications through AWS SNS and SwiftUI
Tags: aws, apns, ios, swiftui
Published: 2021-12-22 11:52:31

This article will show you how you can setup Apple Push Notifications (APNS) and send push messages through AWS SNS.

Prerequisite to send a push notification with the information in this article:

- Mac
- Xcode with min version 11
- iPhone device
- Apple Developer account
- AWS Account

---

## Step 1: Create an iOS app
1. Start Xcode
2. Choose App, a product name and the rest can be chosen as you prefer but make sure to select SwiftUI
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vbg7zlndu284bzeq0wvo.png)
3. When you have created your app click on the projects name in the top left corner
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1h8n7z46fszszstmat1c.png)
4. Now click on Signing & Capabilities and make sure you have signed in to your Apple Developer account
5. Next click on + Capability and search for Push Notifications and add it 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wizqgnqmc9621pc50j1k.png)

You should now have a view looking like this:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhz32fplg7d5htfg5h8v.png)

---

## Step 2: Setup AWS SNS
1. Go to AWS and SNS
2. On the left side click on Push notifications
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5x5byu6w9ivgmkhyeun.png)
3. Now click on Create platform application
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qnds4wwjj03z8shent85.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxb7ckrjxletvxjsw2b7.png)
4. Select Token (you could also choose certificate and download your p12 file)
5. Now head back to [developer.apple.com ](developer.apple.com) and select Keys in the left menu
6. Now create a new key for Apple Push Notifications service (APNs) and follow the steps
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8irhorz0jvkvkw9ypca.png)
7. You will now download a p8 file and also get a Signing key ID. Add these to the AWS portal
8. The Team ID is the value right to your username top right
9. Bundle ID is the app identification ID which can be found by opening Xcode select your project (top left) and then select General and then copy the Bundle Identifier value
10. Now select Create and if everything is OK the you have successfully created a platform application using APNs token-based authentication
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5ccf2ghg8re8j10eel4.png)

---

## Step 3: Implement support for Push in app
First of all we need a class that will handle our registration for push notifications and also for getting our device token:

In your **SNSPushDemo.swift** and add the following code in that file (note that this is the name of your project, if you have called your project something else then it will be called that instead):

```swift
import SwiftUI

@main
struct SNSPushDemoApp: App {
    @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("Device Token: \(token)")
    };
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
       print(error.localizedDescription)
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .badge, .sound])
    }
}
```

Now in our **ContentView.swift**, we will update that class so that we 

1. Prompt the user with a request to send push notifications
2. Allows the user to register the device so that we get a device token

```swift
import SwiftUI

struct ContentView: View {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    init() {
        requestPushAuthorization();
    }
    
    var body: some View {
        Button("Register for notifications") {
            registerForNotifications();
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

func requestPushAuthorization() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
        if success {
            print("Push notifications allowed")
        } else if let error = error {
            print(error.localizedDescription)
        }
    }
}

func registerForNotifications() {
    UIApplication.shared.registerForRemoteNotifications()
}
```

---

## Step 4: Setup all settings and prepare for a push
Let´s start by starting your application on you device. You should be prompted with a message saying:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ykg89olx99fquvqggdx.png)

You will get this message because we have added the following snippet in our ContentView class:

```swift
func requestPushAuthorization() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
        if success {
            print("Push notifications allowed")
        } else if let error = error {
            print(error.localizedDescription)
        }
    }
}
```

Which we are calling when we enter the class within the:

```swift
init() {
    requestPushAuthorization();
}
```
If we succeed to authorize we will print out:

```
Push notifications allowed
```

The next step is to get our Device Token. Start the application and click the button **Register for notifications**. You will now get a Device Token in the output window. Copy that value.

Before we continue, let´s explain what a device token is:
_A device token is a unique key, created and assigned by Apple or Google to create a connection between an app and an iOS, Android. This key is unique based on your device and application installation. That means that you will get a new device token everytime you re-install the application._

Now go back to the AWS Console and click on **Create application endpoint**:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd1p25rofxmy44xlwqb0.png)

In the next view you need to add a device token but you are also able to add user data. User data is data that you can pass with a push which can be used to show unique information. 

Let´s say for example that you have a news app and you get a notification for an article, when you click on that push you want to open that specific article and to do that you could pass that article id in the user data for example.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j921jbjdououu526urhn.png)

---

## Step 5: send a push
Now in the AWS Console simple click on Publish message
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nq82jne36khphbc0er91.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4vca354ed6cu32wjww1l.png)

And when you publish the message you should now receive a push notification to your device:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpvofv6j6rzhxsixte4e.jpeg)