🎉 New! Web Push Notifications for Chatkit. Learn more in our latest blog post.
Hide
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

Rich notifications with Vapor - Part 1: Building the backend

  • Christopher Batin

March 14th, 2019
You will need Xcode 10+, Vapor 3+, Cocoapods, and some understanding of Vapor.

Introduction

In this tutorial we are going to build our backend service using Vapor. It will be responsible for sending a notification to our iOS application.

Sometimes sending notifications with only text just isn’t quite enough. This is where rich notifications come in. We can add images and videos to our notification to give the user a richer experience directly from their notification center.

Prerequisites

  • A basic understanding of Vapor - please complete my “Getting started with Vapor” Part One and Part Two.
  • Xcode 10+
  • MacOS
  • Vapor 3.0 - Install instructions here.
  • An iOS device for testing notifications.
  • An understanding of iOS development and Xcode environment.
  • Cocoapods - Install instructions here.
  • A REST client such as Postman and a basic understanding of how to use it.

Setting up our Vapor backend

Creating our Vapor project

From a terminal in your working directory enter the following command to create your Vapor application.

     $ vapor new RichNotifyServer
     $ cd RichNotifyServer

Now we will build your application before opening it in Xcode. Remember your first build could take some time to complete. Vapor update will make sure that you have the latest packages.

    $ vapor build
    $ vapor update

Now open your project in Xcode. Remember to open using Xcode you must run the following command in terminal:

    $ vapor xcode -y

Also remember to change the run scheme to be the “run” scheme in case it is not already set to this.

Adding our dependency

We need to add the Pusher Beams package to our Swift Package Manager (SPM). Start by opening the Package.swift file from the project navigator. This is our dependencies management file, a bit like our Podfile or Cartfile in iOS development.

Below the line that gives us our Vapor package dependency:

    .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),

Add the following to add our Pusher Beams dependency:

    .package(url: "git@github.com:pusher/push-notifications-server-swift.git", .branch("master")),

We need to tell SPM what dependencies each target should have. We do this by editing targets section in the same file. Find the line:

.target(name: "App", dependencies: ["FluentSQLite", "Vapor"]),

Edit it so that it becomes:

    .target(name: "App", dependencies: ["FluentSQLite", "Vapor", "PushNotifications"]),

We’ve added the name of our dependency to the array of dependencies for the app target. For more information on the dependency go here and for more information relating to SPM go here. Your Package.swift file should now look something like this:

    // Package.swift
    // swift-tools-version:4.0
    import PackageDescription

    let package = Package(
        name: "RichNotifyServer",
        dependencies: [
            // 💧 A server-side Swift web framework.
            .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
            .package(url: "git@github.com:pusher/push-notifications-server-swift.git", .branch("master")),
            // 🔵 Swift ORM (queries, models, relations, etc) built on SQLite 3.
            .package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0")
        ],
        targets: [
            .target(name: "App", dependencies: ["FluentSQLite", "Vapor", "PushNotifications"]),
            .target(name: "Run", dependencies: ["App"]),
            .testTarget(name: "AppTests", dependencies: ["App"])
        ]
    )

Now we need to close Xcode and install the package and reopen it. It’s best practice in Vapor to create and install files outside of our Xcode project using command line tools and then reopen Xcode using the toolbox command. After closing Xcode run the following command in the terminal in our working directory.

    $ swift build

Reopen Xcode by running:

    $ vapor xcode -y

Creating a Beams instance

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

Complete step one of the iOS setup guide, 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 this page and you will find your Pusher Beams instance ID and secret key, make note of these you will need them later.

Sending notifications

Rich notifications

Rich notifications allow you to send different types of multi-media content. There are specific types of supported content that you can send. You can find up to date information on those content types here. You should also make note of the maximum size these files can be.

Creating our routes

We will be creating a simple application with one post request that we can use in order to send different push notifications using our REST client.

Open your routes.swift file and replace the contents with the following:

    //../Sources/App/routes.swift
    import Vapor
    import Vapor
    // 1
    import PushNotifications
    /// Register your application's routes here.
    public func routes(_ router: Router) throws {
        // 2
        router.post(PushContent.self, at: "push/") { req, data -> String in
            PushNotificationService.send(content: data)
            return "Push Success"
        }
    }

    // 3
    struct PushContent: Content {
        let title: String
        let message: String
        let dataURL: String
    }

    //4
    class PushNotificationService {
        class func send(content: PushContent) throws {
            let pushNotifications = PushNotifications(instanceId: "YOUR_INSTANCE_ID" , secretKey:"YOUR_SECRET_KEY")
            let interests = ["general"]
            let publishRequest = [
                "apns": [
                    "aps": [
                        "alert": [
                            "title": content.title,
                            "body": content.message
                        ],
                        "mutable-content": 1
                    ],
                    "data": [
                        "attachment-url": content.dataURL
                    ]
                ]
            ]
            pushNotifications.publishToInterests(interests, publishRequest, completion: { publishID in
                print("Published \(publishID)")
            })
        }
    }
  1. We need to import the new PushNotifications dependency we have just installed.
  2. Here we create a new POST route that is capable of sending a specific push notification based on the data that is passed in using the wrapper class we have defined below.
  3. This is the structure that our post request is expecting the data to arrive in. This includes a string that contains the URL of the data that we want to show in our notification.
  4. This is our wrapper class. Here we create an instance of the dependency we have installed using the Beams instances ID and secret key you created earlier. We only have one interest in our app (which is general). We create a publish request using for APNS using the message that is passed in using the method call and we then publish this using our dependency. Make note of the "mutable-content" flag in the data structure, this will be intercepted by our notification service extension in iOS to display the data. Also make note of our "data" key that includes our data url. Our application will use this information in order to download the image or video that we have sent.

Hit the run button in Xcode, you should see a message in the console saying it has started and is listening on http://localhost:8080. Leave this running in the background whilst you complete part two.

Conclusion

We’ve learnt how to add a dependency the Beams server side SDK as a dependency to Vapor and setup a basic route that can publish notifications to an iOS app that has registered for the interest. We’ve learnt about the different types of rich push notifications that can be sent and their limitations.

Now that you have a basic backend setup we need to go ahead and create the iOS application that can display these notifications. Stay tuned for part two!

The source code for this project can be found here.

Clone the project repository
  • iOS
  • Swift
  • Beams
  • 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.