BNotify icon
bnotify.com Console FAQ Contact GitLab
Platform · iOS

iOS SDK integration

Add BNotify with Swift Package Manager, enable Push Notifications, drop in bnotify-config.plist, and wire AppDelegate. Optionally add a Notification Service Extension for delivery tracking and rich images.

Create the app in Console first

Before SPM setup, create a project, add an iOS app, and download bnotify-config.plist. Then continue below.

Distribution SPM Minimum iOS 13.0 Product BNotify Repo GitLab

What you get after integration

CapabilityHow it works
Permission promptSDK requests alert, sound, and badge
Device tokenForward the system token to the SDK at launch
Click / dismiss / actionCall trackEvent from the notification response
Delivery (received)Optional Notification Service Extension
In-app messagesModal, card, banner, fullscreen, and image
Default categorybnotify with action OPEN
Dashboard delivers campaigns

The iOS SDK does not send notifications. Register the device, then create and send campaigns from the BNotify dashboard. Upload your Apple Push credentials in the dashboard so iOS devices can receive them.

Prerequisites

RequirementNotes
Xcode 15+SPM + Swift package
Deployment Target ≥ 13.0Matches SDK
Apple Developer ProgramRequired for real-device push
Push Notifications capabilityApp ID + profiles
Physical deviceRequired for real push testing
Dashboard plistDownload bnotify-config.plist after you register the iOS app in Console

Integration checklist

  • 1Add SPM product BNotify to the app target
  • 2Enable Push Notifications capability
  • 3Add bnotify-config.plist to the app target
  • 4Wire register APIs at launch
  • 5Forward the device token / registration error to the SDK
  • 6Implement click/dismiss trackEvent
  • 7App Groups + Notification Service Extension
  • 8Disable verbose logs in Release

Step 1 — Add the Swift Package

  1. Xcode → File → Add Package Dependencies…
  2. Enter: https://gitlab.com/hamza.hafeez/bnotifyiossdk.git
  3. Choose version rule (e.g. Up to Next Major).
  4. Add product BNotify to the main app (and NSE if you create one).
Swift
import BNotify

Step 2 — Apple Developer / Xcode capabilities

  1. Apple Developer → Identifiers → enable Push Notifications on your App ID.
  2. Renew provisioning profiles that include Push.
  3. Upload your Apple Push key (.p8) or certificates in the BNotify dashboard.
  4. In Xcode target → Signing & Capabilities → + Capability → Push Notifications.

For NSE delivery tracking, add the same App Group on the app and extension targets, then set appGroupId in the plist.

Step 3 — Add bnotify-config.plist

Download from the BNotify Console after you register the iOS app (see Create a project). Keep the filename exactly bnotify-config.plist and include it in the main app target membership. The SDK loads it from Bundle.main.

XML
<?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>projectId</key>
    <string>your-project-id</string>
    <key>packageName</key>
    <string>com.example.yourapp</string>
    <key>apiKey</key>
    <string>your-api-key</string>
    <key>appId</key>
    <string>your-app-id</string>
    <key>authDomain</key><string></string>
    <key>databaseURL</key><string></string>
    <key>storageBucket</key><string></string>
    <key>messagingSenderId</key><string></string>
    <key>measurementId</key><string></string>
</dict>
</plist>
Config file

The dashboard download is enough. Do not add extra URL keys to the plist.

Step 4 — Wire AppDelegate

Swift
import UIKit
import UserNotifications
import BNotify

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self

        #if !DEBUG
        BNotifyLog.isEnabled = false
        #endif

        BNotifyManager.shared.registerCategories()
        BNotifyManager.shared.registerForPushNotifications()
        return true
    }

    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        BNotifyManager.shared.didRegisterForRemoteNotifications(token: deviceToken)
    }

    func application(
        _ application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: Error
    ) {
        BNotifyManager.shared.didFailToRegisterForRemoteNotifications(error: error)
    }
}

Keep device-token callbacks on AppDelegate even when using SceneDelegate.

Step 5 — Track clicks, dismissals & actions

Swift
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    let userInfo = response.notification.request.content.userInfo
    let type: String
    let actionId: String

    switch response.actionIdentifier {
    case UNNotificationDismissActionIdentifier:
        type = "dismissed"; actionId = "dismiss"
    case UNNotificationDefaultActionIdentifier:
        type = "clicked"; actionId = "clicked"
    default:
        type = "action"; actionId = response.actionIdentifier
    }

    BNotifyManager.shared.trackEvent(type: type, userInfo: userInfo, actionId: actionId)
    // Optional: navigate from userInfo
    completionHandler()
}
User actionSuggested typeSuggested actionId
Tap bodyclickedclicked
Dismissdismisseddismiss
Tap OpenactionOPEN

Step 6 — Foreground display (optional)

Swift
func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
    if #available(iOS 14.0, *) {
        completionHandler([.banner, .sound, .badge])
    } else {
        completionHandler([.alert, .sound, .badge])
    }
}

Step 7 — Notification Service Extension (recommended)

Use an NSE to report received and attach images for collapsed thumbnail + expanded media (GIF animates natively).

  1. File → New → Target → Notification Service Extension.
  2. Link product BNotify to the extension.
  3. Enable the same App Group on app + extension; set appGroupId in plist.
Swift
import UserNotifications
import BNotify

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
    ) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        BNotifyExtensionSafe.prepareNotificationContent(request) { content in
            contentHandler(content)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler, let bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

In-app messages

In-app campaigns appear inside the app (modal, card, top banner, fullscreen, and image). They are separate from lock-screen notifications. Optional custom triggers:

Swift
BNotifyInApp.start() // optional; also starts from config load
BNotifyInApp.logEvent("purchase_completed")

Rich media payload

For NSE + rich media, include mutable-content: 1 and put imageUrl as a sibling of aps:

JSON
{
  "aps": {
    "alert": { "title": "Hello", "body": "World" },
    "sound": "default",
    "mutable-content": 1,
    "category": "bnotify"
  },
  "notificationId": "n-123",
  "token": "<device-or-tracking-token>",
  "imageUrl": "https://cdn.example.com/promo.gif",
  "isExpanded": true
}
Without mutable-content

If mutable-content is missing, the NSE may not run — no received tracking and no expanded image attachment.

Verification

  1. Run on a physical device with Push capability.
  2. Grant notification permission; confirm the device appears in the BNotify dashboard.
  3. Send a test push from the BNotify dashboard with notificationId and category bnotify.
  4. Tap / dismiss → events appear in analytics.
  5. With NSE: confirm received + image thumbnail / expand.

Troubleshooting

SymptomLikely causeFix
No token / registration failsPush capability or provisioningEnable Push on App ID; use real device
Text-only push, no imageMissing NSE / mutable-content / imageUrlAdd NSE; put imageUrl outside aps
App not found on registerWrong appId / bundleMatch dashboard app + packageName
No dismiss eventsCategory not bnotifyCall registerCategories(); set category in payload
In-app never showsOffline or incomplete initConfirm config load, network, and that registerForPushNotifications() ran
Need help?

See the FAQ or contact support at bnotify93@gmail.com.