iOS (Swift)

Official Pushtifly SDK (Swift Package) with direct APNs and an extension for media and buttons.

The official Pushtifly SDK is a Swift Package for iOS 15 or later. It uses direct APNs and doesn't need Firebase. It does the following:

  • registers the device, with an offline queue;
  • detects the environment (sandbox or production) from the provisioning profile;
  • shows notifications while the app is open;
  • reports opens and clicks;
  • manages users, tags and topics.

It also includes a Notification Service Extension ready to subclass, for images, GIFs, audio, video and buttons.

Requirements

  • The .p8 key or the .p12 certificate uploaded to Pushtifly.
  • In Xcode: Signing & Capabilities > Push Notifications and Background Modes > Remote notifications.

Installation

File > Add Package Dependencies… and add the package. Until it's published, use Add Local… with the sdks/ios folder. Add the Pushtifly product to the app.

Usage

import Pushtifly

final class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        Pushtifly.configure(PushtiflyOptions(appKey: "pk_live_YOUR_PUBLIC_KEY", notificationServiceExtension: true))
        Pushtifly.onNotificationOpened { n in
            // n.deepLink, n.actionId (tapped button), n.data (your data)
        }
        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Pushtifly.didRegisterForRemoteNotifications(deviceToken: deviceToken)
    }
}

// Once the user understands what it's for:
Pushtifly.requestPermission { state in }

Pushtifly.identify("customer-123")
Pushtifly.setTags(["plan": "gold"])
Pushtifly.subscribe("offers")
Pushtifly.pairTestDevice(code: "483920") { ok in }
Pushtifly.logout()

In SwiftUI, connect the AppDelegate with @UIApplicationDelegateAdaptor.

The SDK installs itself as the UNUserNotificationCenter delegate and forwards everything to whatever delegate was there before. If you'd rather handle it yourself, use setsNotificationCenterDelegate: false and call Pushtifly.handleWillPresent(_:) and Pushtifly.handleResponse(_:) from yours.

PushtiflyOptions options

Option Default Description
appKey — Public key pk_live_… or pk_test_…. The SDK rejects secret keys.
appId — Only if the key isn't restricted to one app.
environment .auto .sandbox or .production to force the APNs environment.
autoRegister false Ask for permission at launch.
foregroundDisplay true Show notifications while the app is open.
notificationServiceExtension false The app includes the extension; enables images and buttons.
setsNotificationCenterDelegate true The SDK handles UNUserNotificationCenter.
debug false Logs in the console.

With Firebase Messaging

If your app already uses Firebase on iOS, pass the FCM token instead of the APNs one: Pushtifly.setFCMToken(token). In Pushtifly, set up iOS via FCM.

Images, GIFs, audio, video and buttons

  1. File > New > Target > Notification Service Extension.
  2. Add the PushtiflyNotificationService product to that target.
  3. Replace its class:
import PushtiflyNotificationService

class NotificationService: PushtiflyNotificationServiceExtension {}
  1. Start the SDK with notificationServiceExtension: true.

Pushtifly sets mutable-content: 1 when there's media or buttons.

What the SDK reports

Event When
received The notification arrives while the app is open.
opened The user taps the notification.
clicked The user taps a button (includes actionId).
permission_granted / permission_denied The permission changes.

Without the SDK (REST)

Convert the token to hexadecimal (deviceToken.map { String(format: "%02x", $0) }.joined()) and register it with POST /v1/devices, with platform: "ios", environment: "auto" and framework: "native_ios". On open, read _phid and deepLink from userInfo and report opened (or clicked with actionIdentifier) to /v1/events.