Integration guide

Add the Blaink SDK to an iOS, Android, React Native or web app: install it, register the device, handle links. Signed in, your own platform's keys are filled into every sample.

iOS 13.0+
Swift 5.10+
Xcode 15.0+

iOS Integration

Get started with Blaink SDK for iOS in just a few simple steps. Our SDK is designed to be lightweight and easy to integrate.

1

Installation via Swift Package Manager

Add the Blaink SDK to your Xcode project using Swift Package Manager:

Package.swift
dependencies: [
    .package(url: "https://git.blainks.com/blainks/blainks-ios.git", from: "1.3.69")
]

Via Xcode UI

  1. Go to File > Add Package Dependencies
  2. Enter the repository URL: https://git.blainks.com/blainks/blainks-ios.git
  3. Select the version and click Add Package
2

Enable Push Notifications Capability

Configure your Xcode project to receive push notifications:

1 Select your project target
2 Go to Signing & Capabilities
3 Click + Capability
4 Add Push Notifications
5 Add Background Modes and enable Remote notifications
3

Choose Registration Method

The SDK supports two methods for handling device token registration and deeplinks. Choose the one that best fits your needs:

Automatic Registration

Uses method swizzling to automatically intercept the device token from APNs and handle deeplinks. This is the simplest integration method with minimal code required.

AppDelegate.swift
import Blainks
                    import SwiftUI

                    class AppDelegate: NSObject, UIApplicationDelegate {
                        func application(
                            _ application: UIApplication,
                            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
                        ) -> Bool {
                            // Enable automatic device token registration (uses method swizzling)
                            Blaink.enableAutoTokenRegistration()

                            // Enable automatic deeplink handling (uses method swizzling)
                            Blaink.enableAutoDeeplinkHandling()

                            // Setup Blaink SDK
                            Blaink.shared.setup(
                                sdkKey: "YOUR_SDK_KEY",
                                environment: .production,  // or .development for sandbox
                                isDebugLogsEnabled: false
                            )
                            Blaink.shared.delegate = self

                            // Register for remote notifications (requests permission + registers with APNs)
                            Blaink.shared.registerForRemoteNotifications()

                            return true
                        }
                    }

                    extension AppDelegate: BlainkDelegate {
                        func didReceiveNotification(_ notification: [AnyHashable: Any]) {
                            // Handle notification tap
                            print("User tapped notification: \(notification)")
                        }

                        func didRegisterForBlainkNotifications(blainkUserId: String) {
                            // SDK successfully registered with Blaink servers
                            print("Registered with Blaink, user ID: \(blainkUserId)")
                        }
                    }
AppDelegate.swift
import UIKit
                    import Blainks

                    @main
                    class AppDelegate: UIResponder, UIApplicationDelegate {

                        func application(
                            _ application: UIApplication,
                            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
                        ) -> Bool {
                            // Enable automatic device token registration (uses method swizzling)
                            Blaink.enableAutoTokenRegistration()

                            // Enable automatic deeplink handling (uses method swizzling)
                            Blaink.enableAutoDeeplinkHandling()

                            // Setup Blaink SDK
                            Blaink.shared.setup(
                                sdkKey: "YOUR_SDK_KEY",
                                environment: .production,
                                isDebugLogsEnabled: false
                            )
                            Blaink.shared.delegate = self

                            // Register for remote notifications (requests permission + registers with APNs)
                            Blaink.shared.registerForRemoteNotifications()

                            return true
                        }
                    }

                    extension AppDelegate: BlainkDelegate {
                        func didReceiveNotification(_ notification: [AnyHashable: Any]) {
                            // Handle notification tap
                            print("User tapped notification: \(notification)")
                        }

                        func didRegisterForBlainkNotifications(blainkUserId: String) {
                            // SDK successfully registered with Blaink servers
                            print("Registered with Blaink, user ID: \(blainkUserId)")
                        }
                    }

Manual Registration

Gives you full control over device token handling and deeplinks. Use this if method swizzling conflicts with other SDKs in your project or if you prefer explicit control.

AppDelegate.swift
import Blainks
                    import SwiftUI

                    class AppDelegate: NSObject, UIApplicationDelegate {
                        func application(
                            _ application: UIApplication,
                            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
                        ) -> Bool {
                            // Do NOT call Blaink.enableAutoTokenRegistration()
                            // Do NOT call Blaink.enableAutoDeeplinkHandling()

                            // Setup Blaink SDK
                            Blaink.shared.setup(
                                sdkKey: "YOUR_SDK_KEY",
                                environment: .production,
                                isDebugLogsEnabled: false
                            )
                            Blaink.shared.delegate = self

                            // Register for remote notifications
                            Blaink.shared.registerForRemoteNotifications()

                            return true
                        }

                        // Manually forward the device token to Blaink
                        func application(
                            _ application: UIApplication,
                            didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
                        ) {
                            Blaink.shared.registerForRemoteNotificationsWithDeviceToken(deviceToken)
                        }

                        // Optional: Handle registration failure
                        func application(
                            _ application: UIApplication,
                            didFailToRegisterForRemoteNotificationsWithError error: Error
                        ) {
                            print("Failed to register for remote notifications: \(error)")
                        }
                    }

                    extension AppDelegate: BlainkDelegate {
                        func didReceiveNotification(_ notification: [AnyHashable: Any]) {
                            print("User tapped notification: \(notification)")
                        }

                        func didRegisterForBlainkNotifications(blainkUserId: String) {
                            print("Registered with Blaink, user ID: \(blainkUserId)")
                        }
                    }

Manual Deeplink Handling Required

When using manual registration, you must also handle deeplinks manually in your YourApp.swift file. See the URL Scheme Setup section below for the complete code.

AppDelegate.swift
import UIKit
                    import Blainks

                    @main
                    class AppDelegate: UIResponder, UIApplicationDelegate {

                        func application(
                            _ application: UIApplication,
                            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
                        ) -> Bool {
                            // Do NOT call Blaink.enableAutoTokenRegistration()
                            // Do NOT call Blaink.enableAutoDeeplinkHandling()

                            // Setup Blaink SDK
                            Blaink.shared.setup(
                                sdkKey: "YOUR_SDK_KEY",
                                environment: .production,
                                isDebugLogsEnabled: false
                            )
                            Blaink.shared.delegate = self

                            // Register for remote notifications
                            Blaink.shared.registerForRemoteNotifications()

                            return true
                        }

                        // Manually forward the device token to Blaink
                        func application(
                            _ application: UIApplication,
                            didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
                        ) {
                            Blaink.shared.registerForRemoteNotificationsWithDeviceToken(deviceToken)
                        }

                        // Optional: Handle registration failure
                        func application(
                            _ application: UIApplication,
                            didFailToRegisterForRemoteNotificationsWithError error: Error
                        ) {
                            print("Failed to register for remote notifications: \(error)")
                        }

                        // Manually handle deeplinks
                        func application(
                            _ app: UIApplication,
                            open url: URL,
                            options: [UIApplication.OpenURLOptionsKey: Any] = [:]
                        ) -> Bool {
                            return Blaink.shared.handleDeeplink(url)
                        }
                    }

                    extension AppDelegate: BlainkDelegate {
                        func didReceiveNotification(_ notification: [AnyHashable: Any]) {
                            print("User tapped notification: \(notification)")
                        }

                        func didRegisterForBlainkNotifications(blainkUserId: String) {
                            print("Registered with Blaink, user ID: \(blainkUserId)")
                        }
                    }
4

URL Scheme Setup (for Deeplinks)

To handle deeplinks from notifications, add a URL scheme to your app:

1 In Xcode, select your project target
2 Go to Info tab
3 Expand URL Types
4 Click + to add a new URL type
5 Set URL Schemes to: YOUR_DEEPLINK_SCHEME

Replace Deeplink Scheme

Replace YOUR_DEEPLINK_SCHEME with your app's deeplink scheme (provided by Blaink). You can use the platform selector above to auto-fill your credentials.

Manual Registration Only: SwiftUI Deeplink Handling

If you chose Manual Registration with SwiftUI, you need to handle deeplinks in your app entry point:

YourApp.swift (Manual Registration Only)
import Blainks
        import SwiftUI

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

            var body: some Scene {
                WindowGroup {
                    ContentView()
                        .onOpenURL { url in
                            // Manually handle deeplinks
                            _ = Blaink.shared.handleDeeplink(url)
                        }
                }
            }
        }

Automatic Registration

If you're using Automatic Registration with Blaink.enableAutoDeeplinkHandling(), deeplinks are handled automatically and you don't need the .onOpenURL modifier.

5

Add Notification Service Extension Optional but Recommended

For tracking notification delivery, add a Notification Service Extension:

1 In Xcode, go to File > New > Target
2 Select Notification Service Extension
3 Name it (e.g., NotificationService)
4 Add Blainks SDK to the extension target
NotificationService.swift
import UserNotifications
        import Blainks

        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

                // Track delivery with Blainks
                Task {
                    await Blaink.shared.didReceive(request)
                }

                // Deliver the notification
                if let bestAttemptContent {
                    contentHandler(bestAttemptContent)
                }
            }

            override func serviceExtensionTimeWillExpire() {
                // Called just before the extension will be terminated by the system.
                if let contentHandler, let bestAttemptContent {
                    contentHandler(bestAttemptContent)
                }
            }
        }

API Reference

Blaink

MethodDescription
Blaink.sharedShared singleton instance
Blaink.enableAutoTokenRegistration()Enables automatic device token forwarding via method swizzling. Call this before setup() if using automatic registration.
Blaink.enableAutoDeeplinkHandling()Enables automatic deeplink handling via method swizzling. Swizzles both application(_:open:options:) for UIKit apps and scene(_:openURLContexts:) for SwiftUI/Scene-based apps (iOS 13+). Call this before setup() if using automatic handling.
setup(sdkKey:environment:isDebugLogsEnabled:)Initialize the SDK with your API key
registerForRemoteNotifications()Request notification permission and register with APNs
registerForRemoteNotificationsWithDeviceToken(_:)Manually register device token with Blaink (use this if not using auto registration)
handleDeeplink(_:)Manually handle deeplinks from notifications (use this if not using auto handling)
didReceive(_:) asyncCalled from Notification Service Extension to track delivery. This is an async method - use Task { await Blaink.shared.didReceive(request) }

BlainkDelegate

MethodDescription
didReceiveNotification(_:)Called when user taps a notification
didRegisterForBlainkNotifications(blainkUserId:)Called when SDK successfully registers with Blaink servers

PushEnvironment

ValueDescription
.productionUse APNs production environment
.developmentUse APNs sandbox environment
Android API 21+
Kotlin 1.9.20+
FCM Required

Android Integration

Get started with Blaink SDK for Android. Features include FCM integration, automatic deeplink handling, SSL pinning, and secure storage.

1

Installation

Add the Blaink SDK to your project:

First, add our Maven repository to your settings.gradle.kts:

settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://blainks.com/maven") }
    }
}

Then add the dependency to your app's build.gradle.kts:

build.gradle.kts (app)
dependencies {
    implementation("com.blainks:blaink:1.0.0")
}
2

Add Firebase to Your Project

Follow the Firebase Android setup guide to add Firebase to your project:

1 Add google-services.json to your app module
2 Apply the Google Services plugin in your build.gradle.kts
build.gradle.kts (app)
plugins {
    id("com.google.gms.google-services")
}
3

Update AndroidManifest.xml

Add the Blaink FCM service and deeplink intent filter:

AndroidManifest.xml
<application ...>

    <!-- Blaink FCM Service -->
    <service
        android:name="com.blaink.push.BlainkFCMService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <!-- Blaink Notification Dismiss Receiver (for tracking dismissed notifications) -->
    <receiver
        android:name="com.blaink.push.NotificationDismissReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="BLAINK_NOTIFICATION_DISMISS" />
        </intent-filter>
    </receiver>

    <!-- Add deeplink support to your launcher activity -->
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <!-- Blaink Deeplink Handler -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="YOUR_DEEPLINK_SCHEME" />
        </intent-filter>
    </activity>

</application>

Replace Deeplink Scheme

Replace YOUR_DEEPLINK_SCHEME with your app's deeplink scheme (provided by Blaink). You can use the platform selector above to auto-fill your credentials.

4

Initialize the SDK

Create or update your Application class:

MyApplication.kt
class MyApplication : Application(), BlainkDelegate {

    override fun onCreate() {
        super.onCreate()

        Blaink.getInstance().apply {
            delegate = this@MyApplication
            setup(
                context = this@MyApplication,
                sdkKey = "YOUR_SDK_KEY",
                environment = PushEnvironment.PRODUCTION,
                isDebugLogsEnabled = BuildConfig.DEBUG
            )
        }
    }

    override fun didReceiveNotification(notification: Map<String, Any>) {
        // Called when a push notification is received
        Log.d("Blaink", "Notification received: $notification")
    }

    override fun didRegisterForBlainkNotifications(blainkUserId: String) {
        // Called when device is successfully registered with Blaink
        Log.d("Blaink", "Registered with user ID: $blainkUserId")
    }
}

Replace SDK Key

Replace YOUR_SDK_KEY with your platform's SDK key (provided by Blaink). You can use the platform selector above to auto-fill your credentials.

Register your Application class in AndroidManifest.xml:

AndroidManifest.xml
<application
    android:name=".MyApplication"
    ...>
5

Register for Push Notifications

In your main activity, call registerForRemoteNotifications():

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Register for push notifications
        // This automatically:
        // - Requests POST_NOTIFICATIONS permission on Android 13+
        // - Fetches the FCM token
        // - Registers with Blaink backend
        Blaink.getInstance().registerForRemoteNotifications(this)
    }
}

That's it!

The SDK automatically handles:

  • FCM token retrieval and registration
  • Notification permission requests (Android 13+)
  • Deeplink handling via ActivityLifecycleCallbacks

Advanced Usage

Manual FCM Token Registration

If you manage FCM tokens yourself:

Manual Token Registration
FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
    Blaink.getInstance().registerFCMToken(token)
}

Manual Deeplink Handling

The SDK automatically handles deeplinks, but you can also handle them manually:

Manual Deeplink Handling
// Returns true if the deeplink was handled by Blaink
val handled = Blaink.getInstance().handleDeeplink(uri.toString())

Session Management

Session Management
// Check if user is authenticated
if (UserSession.isAuthenticated) {
    // User is logged in
}

// Get current user
lifecycleScope.launch {
    val result = Blaink.getInstance().getCurrentUser()
    result.onSuccess { userId ->
        Log.d("Blaink", "User ID: $userId")
    }
}

// Logout
lifecycleScope.launch {
    val result = Blaink.getInstance().logout()
    result.onSuccess {
        Log.d("Blaink", "Logged out successfully")
    }
}

ProGuard / R8 Configuration

Add these rules to your proguard-rules.pro:

proguard-rules.pro
# Blaink SDK
-keep class com.blaink.** { *; }
-dontwarn com.blaink.**

# Kotlinx Serialization
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt

API Reference

Blaink

MethodDescription
Blaink.getInstance()Get the singleton instance
setup(context, sdkKey, environment, isDebugLogsEnabled)Initialize the SDK with your configuration
registerForRemoteNotifications(activity)Request permission, fetch FCM token, and register with Blaink (recommended)
registerFCMToken(token)Manually register an FCM token with Blaink
handleDeeplink(url)Manually handle a deeplink URL. Returns true if handled.
getCurrentUser()Get the current user ID (suspend function)
logout()Logout and unregister from push notifications (suspend function)
trackNotificationAction(notificationId, action)Track notification interactions (opened, dismissed)

BlainkDelegate

MethodDescription
didReceiveNotification(notification)Called when a push notification is received (delivered)
didRegisterForBlainkNotifications(blainkUserId)Called when device is successfully registered with Blaink

PushEnvironment

ValueDescription
PushEnvironment.PRODUCTIONUse for production/release builds
PushEnvironment.DEVELOPMENTUse for debug/development builds
React Native 0.75+
iOS 13.0+
Android API 21+

React Native Integration

Get started with Blaink SDK for React Native. The react-native-blaink package is a thin bridge that wraps the native iOS and Android SDKs — zero business logic lives in the JavaScript layer.

1

Installation

Install the package from npm:

Terminal
npm install react-native-blaink

iOS — Swift Package Manager

The iOS native SDK is added automatically via SPM when you run pod install. No CocoaPods dependency is required for the Blaink SDK itself.

Android — Maven Repository

Add the Blaink Maven repository to your project-level build.gradle or settings.gradle.kts:

android/build.gradle
allprojects {
    repositories {
        maven { url "https://blainks.com/maven" }
    }
}
2

Platform Setup

iOS

1 Open your Xcode project and select your app target
2 Go to Signing & Capabilities
3 Add Push Notifications capability
4 Add Background Modes and enable Remote notifications

Android

1 Add google-services.json to android/app/
2 Apply the Google Services plugin in your build.gradle

Add the Blaink FCM service and deeplink intent filter to your AndroidManifest.xml:

android/app/src/main/AndroidManifest.xml
<application ...>

    <!-- Blaink FCM Service -->
    <service
        android:name="com.blaink.push.BlainkFCMService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <!-- Blaink Notification Dismiss Receiver -->
    <receiver
        android:name="com.blaink.push.NotificationDismissReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="BLAINK_NOTIFICATION_DISMISS" />
        </intent-filter>
    </receiver>

    <!-- Add deeplink support to your main activity -->
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:launchMode="singleTask">

        <!-- Blaink Deeplink Handler -->
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="YOUR_DEEPLINK_SCHEME" />
        </intent-filter>
    </activity>

</application>

Also add the deeplink scheme to your iOS Info.plist:

ios/YourApp/Info.plist
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>YOUR_DEEPLINK_SCHEME</string>
        </array>
    </dict>
</array>

Replace Credentials

Replace YOUR_DEEPLINK_SCHEME with the deeplink scheme provided by Blaink for each platform. You can use the platform selector above to auto-fill your credentials.

3

Initialize the SDK

Initialize Blaink in your app's entry point. Call setup() once, and register event listeners to receive notifications and registration callbacks:

App.tsx
import { useEffect } from 'react';
import { Platform } from 'react-native';
import {
  Blaink,
  PushEnvironment,
  addNotificationListener,
  addRegistrationListener,
} from 'react-native-blaink';

const SDK_KEY = Platform.select({
  ios: '<span class="sdk-key-placeholder">YOUR_IOS_SDK_KEY</span>',
  android: '<span class="sdk-key-placeholder">YOUR_ANDROID_SDK_KEY</span>',
})!;

export default function App() {
  useEffect(() => {
    // Initialize the SDK
    Blaink.setup({
      sdkKey: SDK_KEY,
      environment: PushEnvironment.PRODUCTION,
      debugLogsEnabled: __DEV__,
    });

    // Listen for push notifications
    const notifSub = addNotificationListener((payload) => {
      console.log('Notification:', payload);
    });

    // Listen for Blaink registration
    const regSub = addRegistrationListener((blainkUserId) => {
      console.log('Registered:', blainkUserId);
    });

    return () => {
      notifSub.remove();
      regSub.remove();
    };
  }, []);

  // ...
}

Replace SDK Keys

Replace YOUR_IOS_SDK_KEY and YOUR_ANDROID_SDK_KEY with your platform SDK keys (provided by Blaink). You can use the platform selector above to auto-fill your credentials.

4

Register for Push Notifications

Call registerForRemoteNotifications() to request permission and register the device with Blaink:

Push Registration
import { Blaink } from 'react-native-blaink';

async function registerPush() {
  try {
    await Blaink.registerForRemoteNotifications();
    console.log('Push registration requested');
  } catch (error) {
    console.error('Push registration failed:', error);
  }
}

Automatic Handling

This single call handles everything per platform:

  • iOS: Requests notification permission and registers the APNs token
  • Android: Requests POST_NOTIFICATIONS permission (Android 13+), fetches the FCM token, and registers with Blaink
5

Handle Deeplinks

Handle incoming deeplink URLs via the SDK:

Deeplink Handling
import { Blaink } from 'react-native-blaink';
import { Linking } from 'react-native';

// Listen for deeplinks from React Native's Linking API
Linking.addEventListener('url', async ({ url }) => {
  const handled = await Blaink.handleDeeplink(url);
  if (!handled) {
    // Handle non-Blaink deeplinks yourself
  }
});
6

Add Notification Service Extension (iOS) Optional but Recommended

To track notification delivery (read/dismiss states), add a Notification Service Extension to your iOS project. This is a separate target that runs outside your React Native app — it intercepts notifications before they are displayed.

1 In Xcode, go to File > New > Target
2 Select Notification Service Extension
3 Name it (e.g., NotificationService)
4 Add the Blainks SDK to the extension target via your Podfile (see below)

Add the extension target to your Podfile:

ios/Podfile
# Add after your main app target block

target 'NotificationService' do
  pod 'BlainkNotificationService', :path => '.'
end

Create a local podspec that wraps the Blainks SPM dependency for the extension:

ios/BlainkNotificationService.podspec
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve("react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]})',
  __dir__ + '/..'
]).strip

Pod::Spec.new do |s|
  s.name         = "BlainkNotificationService"
  s.version      = "1.0.0"
  s.summary      = "Blainks SDK for Notification Service Extension"
  s.homepage     = "https://blainks.com"
  s.license      = "MIT"
  s.authors      = "Blaink"
  s.platforms    = { :ios => "13.0" }
  s.source       = { :git => "" }
  s.source_files = "NotificationService/**/*.swift"

  spm_dependency(s,
    url: 'https://git.blainks.com/blainks/blainks-ios.git',
    requirement: { kind: 'upToNextMajorVersion', minimumVersion: '1.3.69' },
    products: ['Blainks']
  )
end

Then run cd ios && pod install to link the dependency.

Why a local podspec?

The main app gets the Blainks SDK through CocoaPods via spm_dependency in the library podspec. Extension targets need the same mechanism — a local podspec that uses spm_dependency to resolve the SPM package for the extension.

NotificationService.swift
import UserNotifications
import Blainks

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

        // Track delivery with Blainks
        Task {
            await Blaink.shared.didReceive(request)
        }

        // Deliver the notification
        if let bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler, let bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}
Why is this needed? Without this extension, the Blaink backend cannot tell whether a notification was actually delivered to the device. The extension calls Blaink.shared.didReceive(request) which reports delivery back to the server, enabling read/dismiss analytics in your dashboard.

This is pure native code

The Notification Service Extension runs in a separate process outside of React Native. It imports Blainks directly — no bridge code is needed. The extension's bundle identifier should be your.app.bundle.id.NotificationService.

7

Analytics

Track events, screens, and user properties with the built-in analytics module:

Analytics
import { analytics } from 'react-native-blaink';

// Track a custom event
analytics.log('purchase_completed', {
  productId: '12345',
  amount: 29.99,
});

// Track screen view
analytics.setScreen('ProductDetail', 'App');

// Set user properties
analytics.setUserProperty('premium', 'true');
analytics.setUser({ tier: 'premium', region: 'eu' });

// Flush pending events
analytics.flush();
8

Localisation

Server-synced translations with local fallback:

Localisation
import { localisation } from 'react-native-blaink';

// Sync translations from the backend
const updatedKeys = await localisation.sync();

// Get a translated string
const title = await localisation.getString('welcome_title');

// Get translation for a specific language
const titleDE = await localisation.getString('welcome_title', 'de');

// Get current language
const lang = await localisation.getLanguage();

// Set active language
localisation.setLanguage('fr');

// Get all available languages
const languages = await localisation.getAvailableLanguages();

API Reference

Blaink

MethodDescription
Blaink.setup(config)Initialize the SDK with sdkKey, environment, and debugLogsEnabled
Blaink.registerForRemoteNotifications()Request push permission and register device with Blaink. Returns Promise<void>
Blaink.registerDeviceToken(token)Manually register a device token (APNs/FCM)
Blaink.handleDeeplink(url)Handle a deeplink URL. Returns Promise<boolean>

Event Listeners

FunctionDescription
addNotificationListener(callback)Fires when a push notification is received
addRegistrationListener(callback)Fires when the device is registered with Blaink (returns blainkUserId)
addDeferredDeeplinkResolvedListener(callback)Fires when a deferred deeplink is resolved on first install
addDeferredDeeplinkFailedListener(callback)Fires when deferred deeplink resolution fails

analytics

MethodDescription
analytics.log(name, params?)Track a custom event with optional parameters
analytics.setScreen(name, screenClass?, properties?)Track a screen view with optional class and properties
analytics.setUserProperty(name, value)Set a single user property
analytics.setUser(properties)Set multiple user properties at once
analytics.flush()Flush pending analytics events

localisation

MethodDescription
localisation.sync()Sync translations from server. Returns Promise<number | null>
localisation.getString(key, lang?)Get translated string by key. Returns Promise<string>
localisation.getOptionalString(key)Get translated string or null. Returns Promise<string | null>
localisation.getLanguage()Get current language code. Returns Promise<string>
localisation.setLanguage(lang)Set the active language
localisation.getAvailableLanguages()Get list of available languages. Returns Promise<string[]>
localisation.getAllTranslations(key)Get all translations for a key. Returns Promise<Record<string, string>>
localisation.getCachedVersion()Get cached translation version. Returns Promise<number>
localisation.clearCache()Clear local translation cache

PushEnvironment

ValueDescription
PushEnvironment.PRODUCTIONUse for production/release builds
PushEnvironment.DEVELOPMENTUse for debug/development builds

Web Integration

Implement push notifications for your Web Application using Firebase Cloud Messaging (FCM). Supports Chrome, Firefox, Edge, and Safari (iOS 16.4+).

Simple Integration

If your domain is registered in the Blaink Admin Panel, the SDK auto-configures itself. Just add the SDK, create a one-line service worker file, and call Blaink.init()!

1

Add Blaink SDK

Add the Blaink Web SDK to your HTML file (e.g., index.html):

index.html
<!-- Blaink Web SDK -->
<script src="https://blainks.com/blaink.js"></script>
2

Service Worker

Web push needs a service worker at the root of your site. Create firebase-messaging-sw.js in your website's root directory, with the Firebase configuration of your Web platform:

firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.22.0/firebase-messaging-compat.js');

firebase.initializeApp({
  apiKey: 'YOUR_API_KEY',
  authDomain: 'YOUR_PROJECT.firebaseapp.com',
  projectId: 'YOUR_PROJECT_ID',
  storageBucket: 'YOUR_PROJECT.appspot.com',
  messagingSenderId: 'YOUR_SENDER_ID',
  appId: 'YOUR_APP_ID'
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
  const title = payload.notification?.title || 'New Notification';
  return self.registration.showNotification(title, {
    body: payload.notification?.body || '',
    icon: payload.notification?.icon,
    data: payload.data
  });
});

self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  event.waitUntil(clients.openWindow(event.notification.data?.url || '/'));
});
3

Initialize & Register

Initialize the SDK and request notification permission from the user.

User Interaction Required

Browsers require notification permission to be requested from a user gesture (like a button click). You cannot request permission automatically on page load.

Add a button with the special ID blaink-notification-button. The SDK will automatically attach click handlers:

HTML
<!-- SDK auto-attaches click handler to this button -->
<button id="blaink-notification-button">Enable Notifications</button>

Then initialize the SDK at the end of your HTML body (after the button element):

index.html
<script>Blaink.init();</script>

Custom Button Handling

If you prefer to use your own button or trigger, you can manually call Blaink.requestPermission() from any user gesture:

JavaScript
// Custom button click handler
document.getElementById('my-button').addEventListener('click', async () => {
    const token = await Blaink.requestPermission();
    if (token) {
        console.log('Notifications enabled!', token);

        // Optional: Link device to your authenticated user
        const deviceId = localStorage.getItem('blaink_device_id');
        if (deviceId) {
            await fetch('/your-api/link-device', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer ' + userAccessToken
                },
                body: JSON.stringify({ deviceId: deviceId })
            });
        }
    }
});
4

PWA Configuration Optional

For the best experience on iOS Safari, configure your app as a Progressive Web App (PWA). This enables reliable push notifications when users add your site to their home screen.

Add these meta tags to your HTML <head> section:

index.html (head section)
<!-- PWA Configuration -->
<link rel="manifest" href="/manifest.json">

<!-- Apple Touch Icon (use your own icon) -->
<link rel="icon" type="image/png" href="/images/app_icon.png">
<link rel="apple-touch-icon" href="/images/app_icon.png">
<meta name="theme-color" content="#0f172a">

Then create a manifest.json file in your website's root directory:

manifest.json
{
  "name": "Your App Name",
  "short_name": "App",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0f172a",
  "icons": [
    {
      "src": "/images/app_icon.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/images/app_icon.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

iOS Add to Home Screen

On iOS Safari, guide users to tap the Share button and select Add to Home Screen. This creates a standalone app experience with full push notification support.

Important Requirements

HTTPS Required

Web Push requires a Secure Context (HTTPS). It will not work on HTTP (except for localhost).

Safari Support

Supported on macOS (Safari 16+) and iOS (16.4+). For iOS, users must Add to Home Screen for the most reliable experience.

API Reference

Blaink SDK Methods

MethodDescription
Blaink.init([sdkKey])Initialize the SDK. If sdkKey is omitted, auto-configures based on the current domain (domain must be registered in Admin Panel). Loads Firebase and registers the service worker.
Blaink.requestPermission()Request notification permission from the user. Returns a Promise that resolves with the FCM token if granted.
Blaink.onMessage(callback)Register a callback for foreground messages. The callback receives the FCM payload object.

LocalStorage Keys

KeyDescription
blaink_client_idUnique client identifier (UUID) persisted across sessions.
blaink_device_idUnique device identifier (UUID) used to link push tokens to authenticated users.

Service Worker Messages

Message TypeDescription
NOTIFICATION_CLICKSent from service worker when user clicks a notification. Contains url property for navigation.

Stuck somewhere?

The SDKs are open to read, and we answer integration questions within a working day.