Skip to main content

Implementing iOS Push Notifications

If you've completed the steps described in the Setup guide and retrieved the SDK file on the Git repository for app push on iOS, you are now ready to implement our iOS library in your app. Our library supports iOS version 13 and up. Make sure you have the latest Xcode when using this library.

caution

If you are upgrading from an older version of our library, it's always a good idea to read our Migration guide.

Dependencies

The Notificare SDK is compatible with apps supporting iOS 13 and above, and can be installed with Swift Package Manager or CocoaPods.

  1. If you are using the Swift Package Manager, open the menu File > Swift Packages > Add Package Dependency.
  2. In the Choose Package Repository prompt, add the following URL:
https://github.com/Notificare/notificare-sdk-ios.git
  1. Press Next and complete the remaining steps.

For more information on SPM, check their official documentation.

Configuration file

In order to connect your app to Notificare, you need to download the configuration file from the TransferBox of your license (where it was uploaded by the Actito team) and place it under your project's root folder as NotificareServices.plist.

For your reference, here's what this file should look like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>APPLICATION_ID</key>
<string>{{ YOUR APPLICATION ID }}</string>
<key>APPLICATION_KEY</key>
<string>{{ YOUR APPLICATION KEY }}</string>
<key>APPLICATION_SECRET</key>
<string>{{ YOUR APPLICATION SECRET }}</string>
</dict>
</plist>

Bu default, we will create two different apps in Notificare using separated environments for development and production. For each app you will have a different set of keys, resulting in two different configuration files. We recommend you to leverage Xcode's Build Phases to manage which file will be embedded in the application. You read more about it in the Customizations section of the Notificare documentation.

The Notificare Delegate

While this is an optional step, by setting up your own delegate, you can listen to the ready and device_registered events. You can take the opportunity to perform additional steps when Notificare becomes ready or when the device is updated.

extension AppDelegate: NotificareDelegate {
func notificare(_ notificare: Notificare, onReady application: NotificareApplication) {
// At this point you have been assigned a temporary device identifier
// All services subscribed can be used
}

func notificare(_ notificare: Notificare, didRegisterDevice device: NotificareDevice) {
// At this point you know a device is registered with the Notificare API.
// This method will be called once when the device is registered.
}
}

To let Notificare know about your delegate, you can execute the following statement:

Notificare.shared.delegate = self // where self complies with `NotificareDelegate`

Launching Notificare

Launching Notificare is as simple as calling Notificare.shared.launch(). However, before launching, you may want to consider customising some properties.

If you have created a custom delegate, you should also set the Notificare.shared.delegate property to let Notificare know which class will handle the events.

You should launch Notificare when the iOS application is launched. A small code sample can be found below.

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

// In case you want to setup your delegate.
Notificare.shared.delegate = self

// Launch Notificare! 🚀
Notificare.shared.launch { result in
switch result {
case .success:
// Notificare is now ready.
break
case let .failure(error):
// Something went wrong ...
break
}
}
}
}

You can delay launching Notificare for the first time. Otherwise, make sure you launch() during the application's initialization phase to prevent missing important updates when the app is created in the background.

Although launch() is a suspending function (with a callback alternative), you can also use the onReady() method from the NotificareDelegate as shown below when you want to control the state of dependencies in your application initialization flow.

extension AppDelegate: NotificareDelegate {
func notificare(_: Notificare, onReady application: NotificareApplication) {
// Notificare is now safe to use.
}
}

Un-launch Notificare

It is possible to completely remove all data for a device, both locally in your app and remotely in our servers. You want to avoid doing so, but for cases when the user requests their account to be removed, you can use the following method:

Notificare.shared.unlaunch { result in
}

After invoking this, all the device's data will be destroyed and cannot be undone. Once the process is complete, the onUnlaunched method of your NotificareDelegate will be executed.

extension AppDelegate: NotificareDelegate {
func notificareDidUnlaunch(_: Notificare) {
// All device data was deleted.
// Notificare cannot be used until it's launched again.
}
}

At this point, invoking any other method in Notificare will fail, and the only way to start using the SDK again, is by invoking its counterpart, the launch method.

Using SwiftUI

The new SwiftUI App Lifecycle was a good improvement over the traditional initialization process, making it declarative. Just like SwiftUI is meant to be.

However, this change removed the default AppDelegate which means you must supply one yourself. Once you have created the AppDelegate file, you should use the UIApplicationDelegateAdaptor property wrapper to inject it.

@main
struct SampleApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Furthermore, our SDK swizzles the AppDelegate for processing APNS tokens and notifications automatically. Since the internal SwiftUI.AppDelegate breaks our swizzling process, you should disable the swizzling mechanism and forward the relevant methods to our SDK. Check the customizations section for more information.