Push Notifications and In-App MessagingLast Updated: 22/9/2026

Introduction

The Taguchi Push Notifications and In-App Messaging (IAM) SDK allows you to send targeted push notifications and display in-app messages to your mobile app users. The integration is built on top of Twilio Notify and supports three mobile SDK platforms: iOS, Android, and React Native.

Key capabilities include:

  • Sending push notifications to individual subscribers or segments via the Taguchi platform
  • Displaying in-app messages (IAM) to users while they are actively using the app
  • Linking and unlinking device tokens to Taguchi subscriber profiles via the V5 API
  • Handling notification delivery receipts and interaction tracking

Supported platforms

The Taguchi Push and IAM SDK supports the following mobile platforms:

iOS logo iOS
Swift
Android logo Android
Java / Kotlin
React Native logo React Native
iOS & Android

SDK minimum requirements

Before you begin, ensure your project meets the following minimum requirements:

Requirement Minimum version
React Native 0.81.5
iOS 15.0
Android API level 24 (Android 7.0 Nougat)

Twilio Setup

Twilio Notify is used as the notification delivery layer between Taguchi and the device push services (APNs for iOS and FCM for Android). You must set up a Twilio account and configure a Notify Service before proceeding with the SDK installation.

Add Twilio Notify Service

  1. Log in to the Twilio Console.
  2. Navigate to Notify > Services in the left-hand menu.
  3. Click Create new Service.
  4. Enter a friendly name for the service (e.g. taguchi-push).
  5. Click Create.
  6. Note the Service SID — you will need this when configuring the Taguchi integration.

Keep this page open. You will return to it later to upload your APNs certificate and FCM server key.

Creating a new Service in Twilio Notify Creating a new Service in Twilio Notify

Configuring Service in Twilio Notify Configuring Service in Twilio Notify

Libraries

The Taguchi Push and IAM SDK is distributed as three platform libraries: TaguchimailPush for iOS, TaguchimailPush for Android, and taguchimail-mobile-sdk for React Native. Each library subsection below describes what the library does, how to install the SDK for that platform, and its API.

TaguchimailPush (iOS)

TaguchimailPush is an iOS library for handling Taguchi push notifications: it enriches notifications in a notification service extension (sound, image attachments, open tracking), pre-downloads and securely caches In-App Message (IAM) payloads, displays IAMs in the host app, and links subscriber devices to Taguchi.

iOS pre-setup

Complete the following steps in the Apple Developer portal and your local Keychain before modifying the Xcode project.

App Identifier

  1. Log in to the Apple Developer Portal.
  2. Go to Certificates, Identifiers & Profiles > Identifiers.
  3. Select your app's Bundle ID (or create one if it does not yet exist).
  4. Ensure the Push Notifications capability is enabled for the identifier.
  5. Save any changes.

App Group

  1. Still under Identifiers, select your main app's Bundle ID.
  2. Enable the App Groups capability.
  3. Click Configure next to App Groups and add a new group (e.g. group.com.yourcompany.yourapp).
  4. Save and confirm the change.

App Push Certificate

You will need a push certificate to allow Twilio to send notifications via APNs on your behalf. Choose either production only, or a combined production/development certificate depending on your testing needs.

Create a Certificate Signing Request (CSR)
  1. Open Keychain Access on your Mac (or use another CSR tool).
  2. Go to Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.
  3. Enter your email address and a common name. Select Saved to disk and click Continue.
  4. Save the .certSigningRequest file to your desktop.
Create a push certificate (.cer)
  1. In the Apple Developer Portal, go to Certificates, Identifiers & Profiles > Certificates.
  2. Click + to add a new certificate.
  3. Choose Apple Push Notification service SSL (Sandbox & Production) (or Production only, depending on your requirement).
  4. Select your App ID, then upload the .certSigningRequest file you created above.
  5. Download the generated .cer file.
Add .cer to Keychain
  1. Double-click the downloaded .cer file to import it into Keychain Access.
  2. Confirm it appears under the My Certificates category with its associated private key.
Generate .p12 file
  1. In Keychain Access, expand the imported certificate to reveal its private key.
  2. Select both the certificate and the private key (hold ⌘ and click both).
  3. Right-click and choose Export 2 items.
  4. Choose .p12 format, give it a descriptive name (e.g. taguchi-push.p12), and save it.
  5. Set a password when prompted (you will need this password when uploading to Twilio).

Apple Developer Account login Apple Developer Account login

Apple Developer Account identifiersApple Developer Account Identifiers

Apple Developer Account certificatesApple Developer Account Certificates

Generate .pem files to upload to Twilio
  1. Open Terminal and run the following commands to extract the certificate and key from the .p12 file:
openssl pkcs12 -in taguchi-push.p12 -nokeys -out taguchi-push-twilio-cert.pem -nodes -legacy
openssl pkcs12 -in taguchi-push.p12 -nocerts -out taguchi-push-twilio-key.pem -nodes -legacy
openssl rsa -in taguchi-push-twilio-key.pem -out taguchi-push-twilio-rsa-key.pem -traditional
  1. When prompted, enter the .p12 export password.
  2. You now have certificate and RSA key content ready to upload to Twilio Notify:
    • taguchi-push-twilio-cert.pem
    • taguchi-push-twilio-rsa-key.pem

Mobile Push Credentials in Twilio Notify Mobile Push Credentials in Twilio Notify

Creating a new APN Credential in Twilio Notify Creating a new APN Credential in Twilio Notify

iOS installation

App capabilities

Open your project in Xcode and select your main app target under the Signing & Capabilities tab.

Push Notifications

Click + Capability and add Push Notifications.

Background Modes

Click + Capability and add Background Modes.

Remote Notifications

In the Background Modes section, tick the Remote notifications checkbox.

iOS App Provisioning Profile

Ensure your app uses an iOS provisioning profile for the correct bundle identifier (for example: com.company.appname).

Add Push Notification Service Extension

A Notification Service Extension is required to handle notification content modification (e.g. displaying rich media) and delivery receipts.

  1. In Xcode, go to File > New > Target.
  2. Select Notification Service Extension and click Next.
  3. Name it (e.g. TaguchiNotificationServiceExtension) and ensure the language is Swift (or Objective-C if preferred).
  4. Click Finish and activate the scheme when prompted.
  5. Set the extension's deployment target to match your main app (iOS 15.0 or later).

App Group

The main app and the Notification Service Extension must share data via an App Group.

Add App Group to main app target and Notification Service Extension
  1. Select the main app target in Xcode > Signing & Capabilities > + Capability > App Groups.
  2. Add the group you created earlier (e.g. group.com.yourcompany.yourapp).
  3. Repeat steps 1–2 for the Notification Service Extension target, using the same group identifier.

AppDelegate code configuration

Add the following code to AppDelegate.swift.

Note: Your app will need to request notification permission and tracking permission (App Tracking Transparency) at the correct stage of its lifecycle. When to prompt is up to the developer / company — for example (not limited to): at app launch, or after the user logs in.

1. Conform to UNUserNotificationCenterDelegate

Update the AppDelegate class declaration to inherit UNUserNotificationCenterDelegate. This allows AppDelegate to receive notification-related callbacks from the system.

2. didFinishLaunchingWithOptions

Called by the system after the app has finished launching. Used to set the notification categories. Can be used as point to ask for notification and tracking permissions if desired for lifecycle.

Note: TaguchimailPush.addNotificationCategories is optional — only call it if your app uses notification categories (action buttons).

let notificationCategories: [NotificationCategory] = [
    NotificationCategory(
        actions: [
            NotificationAction(title: "Test1", identifier: "TEST1_ACTION"),
            NotificationAction(title: "Test2", identifier: "TEST2_ACTION"),
        ],
        identifier: "EXAMPLE"
    )
]

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

    // Optional — register notification categories (action buttons)
    TaguchimailPush.addNotificationCategories(notificationCenter: notificationCenter, notificationCategories: notificationCategories)

    // Optionally request notification permission here

    return true
}

3. didRegisterForRemoteNotificationsWithDeviceToken

Called by the system after APNs successfully registers the device for push notifications. Converts the binary device token to a hex string and stores it in UserDefaults under the key DeviceToken so the SDK can read it later.

func application(_ application: UIApplication,
                didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenParts = deviceToken.map { String(format: "%02x", $0) }
    let token = tokenParts.joined()

    UserDefaults.standard.set(token, forKey: "DeviceToken")
    UserDefaults.standard.synchronize()

    // Optionally request tracking permission here
}

4. didFailToRegisterForRemoteNotificationsWithError

Called by the system when the system fails to register a device token. Handy for debugging.

func application(
    _ application: UIApplication,
    didFailToRegisterForRemoteNotificationsWithError error: Error
) {
    /// Some error occurred while registering for device token
    /// Add logging as necessary
}

5. application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

Called when a background or foreground remote notification is received. Passes the notification payload to TaguchimailPush so it can process delivery receipts and queue any in-app message data. Replace "group.com.company.appname" with your App Group identifier.

func application(
    _ application: UIApplication,
    didReceiveRemoteNotification userInfo: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
    TaguchimailPush.handleDidReceiveRemoteNotification(userInfo: userInfo, applicationGroupIdentifier: "group.com.company.appname") {
        (data) in
        completionHandler(data)
    }
}

6. userNotificationCenter(_:didReceive:withCompletionHandler:)

Called when the user taps a notification or selects a custom action. Forwards the interaction to TaguchimailPush.performNotificationAction for Taguchi tracking, then calls completionHandler() to signal processing is complete.

func userNotificationCenter(
    _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    TaguchimailPush.performNotificationAction(
        categoryIdentifier: response.notification.request.content.categoryIdentifier,
        actionIdentifier: response.actionIdentifier,
        userInfo: response.notification.request.content.userInfo
    )
    completionHandler()
}

7. userNotificationCenter(_:willPresent:withCompletionHandler:)

Called when the app is in foreground and the notification arrives.

func userNotificationCenter(
    _ center: UNUserNotificationCenter, willPresent notification: UNNotification,
    withCompletionHandler completionHandler:
        @escaping (UNNotificationPresentationOptions) -> Void
) {
    completionHandler([.badge, .sound, .banner])
}

Add target using Notification Service Extension template

The code should look like the following:

import TaguchimailPush
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
    ) {
        self.contentHandler = contentHandler
        TaguchimailPush.handlePushNotificationServiceExtensionDidReceive(
            request, applicationGroupIdentifier: "group.com.company.appname") {
                (content) in
            self.bestAttemptContent = content
            contentHandler(self.bestAttemptContent!)
        }
    }

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

}

Other app configuration

  • Add the taguchimailpush package dependency to your Xcode project from either our repository or from a local copy.
  • Add taguchimailpush to both the App target and the Notification Service Extension target under App > General > Frameworks, Libraries, and Embedded Content.

  • Add a PrivacyInfo.xcprivacy file and complete the privacy nutrition label fields for any data your app collects.

  • Under App > Signing & Capabilities, add the User Notifications usage description to explain why the app requests notification permission.

  • Under App > Info > URL Types, add a URL scheme entry to enable deep link handling from notifications.

What to upload and configure in Twilio

  1. Return to your Twilio Notify Service in the Twilio Console.
  2. Under APN Credential, click Create new credential (or select an existing one).
  3. Paste the certificate from taguchi-push-twilio-cert.pem (including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).
  4. Paste the key from taguchi-push-twilio-rsa-key.pem.
  5. Select Sandbox if sending to a sandbox APNs environment.
  6. Save the credential and capture the APN Credential SID.
  7. Set that APN Credential SID on your Twilio Notify Service.

After completing iOS setup, proceed to Taguchi Credential and Integration Setup.

Push notification capabilities configured in XCode Push notification capabilities configured in XCode

In-App Messaging Usage

To display In-App Messages, add the InAppMessage SwiftUI view to your root view, layered above your app content:

  • ContentView.swift
import SwiftUI
import TaguchimailPush

struct ContentView: View {
    var body: some View {
        ZStack {
            InAppMessage(applicationGroupIdentifier: "group.com.example.app").zIndex(2)

            // Your app content
        }
    }
}

API

Symbol Purpose
TaguchimailPush.handlePushNotificationServiceExtensionDidReceive(_:config:applicationGroupIdentifier:completion:) Enriches an incoming notification (sound, image attachment, open tracking) and pre-downloads/encrypts any referenced IAM payload. Call from a notification service extension.
TaguchimailPush.performNotificationAction(categoryIdentifier:actionIdentifier:userInfo:) Executes the action for a tapped notification or action button — opens deep links/URLs, fires click tracking, and triggers queued IAM display.
TaguchimailPush.handleDidReceiveRemoteNotification(userInfo:applicationGroupIdentifier:completion:) Parses an IAM push payload from userInfo and enqueues it; calls the completion handler with a UIBackgroundFetchResult.
InAppMessage SwiftUI view that displays queued IAMs (fullscreen, partial, top- or bottom-aligned layouts) and handles in-message deep links, clipboard copy, and analytics.
TaguchimailPush.enqueueFromUrl(iamUrl:applicationGroupIdentifier:) / displayEnqueuedIam(applicationGroupIdentifier:) Manually enqueue an IAM from a URL, and trigger display of a queued IAM (no-op when the queue is empty).
TaguchimailPush.linkSubscriberToTaguchi(endpoint:deviceToken:application:subscriberTarget:subscriberIdentifier:) / unlinkSubscriberToTaguchi(endpoint:deviceToken:subscriberTarget:subscriberIdentifier:) Link or unlink a subscriber's APNs device token via the Taguchi /apiv5_unauth/prod/ subscriber endpoint. subscriberTarget must be "ref", "email", or "phone".
TaguchimailPush.addNotificationCategories(notificationCenter:notificationCategories:) Registers notification categories and action buttons with UNUserNotificationCenter.
TaguchimailPushConfig Optional configuration (for example a custom notificationSound) passed to handlePushNotificationServiceExtensionDidReceive.

TaguchimailPush (Android)

TaguchimailPush is an Android (Kotlin) library for handling Taguchi push notifications delivered via Firebase Cloud Messaging: it processes incoming FCM messages (sound, image attachments, open tracking), manages delivery receipts, queues and displays In-App Messages (IAM) in the host app, handles notification deep links, and links subscriber devices to Taguchi.

The Android SDK setup uses Firebase Cloud Messaging and Twilio Notify credentials.

Android pre-setup

Android push notifications are delivered via Firebase Cloud Messaging (FCM). Complete the Firebase setup before modifying your Android project.

Create Project in Firebase

  1. Go to the Firebase Console.
  2. Click Add project, give it a name, and follow the prompts to create it.
Add Android app in Project Settings > General Tab
  1. Inside your Firebase project, click the Android icon (Add app).
  2. Enter your Android package name (must match your app's applicationId in build.gradle).
  3. Optionally enter a nickname and your SHA-1 debug certificate fingerprint.
  4. Click Register app.
  5. Download the google-services.json file when prompted.
Create service account in Google Cloud Console for Push
  1. Open the Google Cloud Console and select your Firebase project.
  2. Go to IAM & Admin > Service Accounts.
  3. Click + Create Service Account.
  4. Give the account the name notifications and click Create and Continue.
  5. Assign both roles:
    • Firebase Cloud Messaging Admin
    • Firebase Cloud Messaging API Admin
  6. Click Done.
  7. Click on the new service account, go to the Keys tab, and click Add Key > Create new key.
  8. Choose JSON and click Create. Download and store the key securely — you will upload this JSON key to Twilio as the FCM Secret Credential.

Firebase Dashboard Firebase Dashboard

Firebase - Add Android App Firebase - Add Android App

Google Cloud - Manage Service Accounts Google Cloud - Manage Service Accounts

What to upload and configure in Twilio

  1. Return to your Twilio Notify Service in the Twilio Console.
  2. Under FCM Credential, click Create new credential.
  3. Upload the JSON service account key file downloaded from Google Cloud Console.
  4. Save the credential and capture the FCM Credential SID.
  5. Set that FCM Credential SID on your Twilio Notify Service.

Mobile Push Credentials in Twilio Notify Mobile Push Credentials in Twilio Notify

Creating a new FCM Credential in Twilio Notify Creating a new FCM Credential in Twilio Notify

Android installation

Add google-services.json to app folder

Copy the google-services.json file downloaded from Firebase into the android/app/ directory of your project:

your-project/
  app/
    google-services.json   ← place it here

Add dependencies to gradle files

Project-level /settings.gradle.kts:

include(":taguchimailpushandroid")

Project-level /build.gradle.kts (plugins section):

plugins {
    id("com.google.gms.google-services") version "4.4.4" apply false
}

App-level /app/build.gradle.kts:

plugins {
    id("com.google.gms.google-services")
}

dependencies {
    implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
    implementation("com.google.firebase:firebase-messaging")
    implementation(project(":taguchimailpushandroid"))
}

Add PushNotificationService.kt to your app

Create PushNotificationService.kt in your app

Location:

your-project/
  app/
    src/
      main/
        com/
          company/
            appname/
              PushNotificationService.kt   ← place it here

Code:

package com.company.appname

import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.taguchi.taguchimailpushandroid.TaguchimailPush


class PushNotificationService: FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        TaguchimailPush.storeDeviceToken(applicationContext, token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        TaguchimailPush.handleMessageReceived(this, message)
    }
}

Add taguchimailpushandroid library module to your project

The taguchimailpushandroid library module must be imported / placed at the project level. This contains the core SDK functionality.

your-project/
  taguchimailpushandroid/

Please see the code available in the repository.

Update AndroidManifest.xml

In /android/app/src/main/AndroidManifest.xml:

Inside <application> > <activity>, add an intent filter for deep link handling:

<intent-filter android:label="Deep Link">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="<deep-link-scheme>" />
</intent-filter>

Inside <application>, register the FCM messaging service:

<service android:name=".PushNotificationService" android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

In-App Messaging Usage

Initialise the TaguchimailPush singleton in your main activity, then include the InAppMessageListener composable in your app content so queued In-App Messages are displayed:

  • MainActivity.kt
package com.example.myapp

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import com.taguchi.taguchimailpushandroid.TaguchimailPush
import com.taguchi.taguchimailpushandroid.TaguchimailPushConfig
import com.taguchi.taguchimailpushandroid.InAppMessageListener
import kotlinx.coroutines.launch


class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        // Initialise the TaguchimailPush singleton (no-op on subsequent calls).
        TaguchimailPush.init(
            context = this,
            config = TaguchimailPushConfig(
                pushNotificationIcon = R.mipmap.app_icon_round
            )
        )

        enableEdgeToEdge(
            statusBarStyle = SystemBarStyle.light(
                android.graphics.Color.TRANSPARENT,
                android.graphics.Color.TRANSPARENT
            )
        )
        setContent {
            AppNameTheme {
                AppNameApp()
            }
        }

    }

}

@Composable
fun AppNameApp() {
    // Your app content

    // Observes the TaguchimailPush IAM queue and shows/dismisses the IAM overlay.
    InAppMessageListener(onNavigateToDeeplink = { deeplink ->
        // Handle in-app message deep links here
    })
}

API

Symbol Purpose
TaguchimailPush.init(context, config) Initialises the singleton and persists the config; safe to call multiple times.
TaguchimailPush.handleMessageReceived(context, message) Processes an FCM RemoteMessage: enqueues a silent IAM or posts a push notification. Works without prior init().
TaguchimailPush.handleTaguchimailPushIntent(intent, coroutineScope) Handles a notification-click Intent (URL, deeplink, or IAM action) and fires click tracking.
TaguchimailPush.storeDeviceToken(context, token) / getDeviceToken(context) Persist/read the FCM device token from SharedPreferences.
TaguchimailPush.displayEnqueuedIam() suspend; dequeues a pre-fetched IAM and triggers display via the listener composable.
TaguchimailPush.fetchAndEnqueueIam(context, iamUrl) suspend; pre-fetches an IAM from a URL outside the push flow and stores it in the queue.
InAppMessageListener(onNavigateToDeeplink) Composable that observes library state and automatically shows/dismisses the IAM overlay.
TaguchimailPushConfig(pushNotificationSound, pushNotificationIcon) Configuration passed to init(): optional custom sound Uri and small-icon drawable resource ID.

taguchimail-mobile-sdk (React Native)

taguchimail-mobile-sdk is a React Native library that wraps the native iOS and Android Taguchi push libraries, exposing a single JavaScript/TypeScript API for permission handling, device tokens, In-App Message display, and subscriber linking.

React Native requires completing both the iOS and Android native setup steps below, plus additional React Native-specific configuration. The native code differs slightly from the pure iOS/Android setups because React Native projects use a different build structure (CocoaPods, Groovy Gradle) and need to bridge native delegates to the JS layer.

iOS pre-setup (React Native)

Complete the following steps in the Apple Developer portal and your local Keychain before modifying the Xcode project.

App Identifier

  1. Log in to the Apple Developer Portal.
  2. Go to Certificates, Identifiers & Profiles > Identifiers.
  3. Select your app's Bundle ID (or create one if it does not yet exist).
  4. Ensure the Push Notifications capability is enabled for the identifier.
  5. Save any changes.

App Group

  1. Still under Identifiers, select your main app's Bundle ID.
  2. Enable the App Groups capability.
  3. Click Configure next to App Groups and add a new group (e.g. group.com.yourcompany.yourapp).
  4. Save and confirm the change.

App Push Certificate

You will need a push certificate to allow Twilio to send notifications via APNs on your behalf. Choose either production only, or a combined production/development certificate depending on your testing needs.

Create a Certificate Signing Request (CSR)
  1. Open Keychain Access on your Mac (or use another CSR tool).
  2. Go to Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.
  3. Enter your email address and a common name. Select Saved to disk and click Continue.
  4. Save the .certSigningRequest file to your desktop.
Create a push certificate (.cer)
  1. In the Apple Developer Portal, go to Certificates, Identifiers & Profiles > Certificates.
  2. Click + to add a new certificate.
  3. Choose Apple Push Notification service SSL (Sandbox & Production) (or Production only, depending on your requirement).
  4. Select your App ID, then upload the .certSigningRequest file you created above.
  5. Download the generated .cer file.
Add .cer to Keychain
  1. Double-click the downloaded .cer file to import it into Keychain Access.
  2. Confirm it appears under the My Certificates category with its associated private key.
Generate .p12 file
  1. In Keychain Access, expand the imported certificate to reveal its private key.
  2. Select both the certificate and the private key (hold ⌘ and click both).
  3. Right-click and choose Export 2 items.
  4. Choose .p12 format, give it a descriptive name (e.g. taguchi-push.p12), and save it.
  5. Set a password when prompted (you will need this password when uploading to Twilio).

Apple Developer Account login Apple Developer Account login

Apple Developer Account identifiersApple Developer Account Identifiers

Apple Developer Account certificatesApple Developer Account Certificates

Generate .pem files to upload to Twilio
  1. Open Terminal and run the following commands to extract the certificate and key from the .p12 file:
openssl pkcs12 -in taguchi-push.p12 -nokeys -out taguchi-push-twilio-cert.pem -nodes -legacy
openssl pkcs12 -in taguchi-push.p12 -nocerts -out taguchi-push-twilio-key.pem -nodes -legacy
openssl rsa -in taguchi-push-twilio-key.pem -out taguchi-push-twilio-rsa-key.pem -traditional
  1. When prompted, enter the .p12 export password.
  2. You now have certificate and RSA key content ready to upload to Twilio Notify:
    • taguchi-push-twilio-cert.pem
    • taguchi-push-twilio-rsa-key.pem

Mobile Push Credentials in Twilio Notify Mobile Push Credentials in Twilio Notify

Creating a new APN Credential in Twilio Notify Creating a new APN Credential in Twilio Notify

iOS installation (React Native)

App capabilities

Open your project in Xcode and select your main app target under the Signing & Capabilities tab.

Push Notifications

Click + Capability and add Push Notifications.

Background Modes

Click + Capability and add Background Modes.

Remote Notifications

In the Background Modes section, tick the Remote notifications checkbox.

iOS App Provisioning Profile

Ensure your app uses an iOS provisioning profile for the correct bundle identifier (for example: com.company.appname).

Install dependent packages

In your project root, install CocoaPods dependencies:

cd ios && pod install && cd ..

Ensure your Podfile targets iOS 15.0 or later:

platform :ios, '15.0'

Add Push Notification Service Extension

A Notification Service Extension is required to handle notification content modification (e.g. displaying rich media) and delivery receipts.

  1. In Xcode, go to File > New > Target.
  2. Select Notification Service Extension and click Next.
  3. Name it (e.g. TaguchiNotificationServiceExtension) and ensure the language is Swift (or Objective-C if preferred).
  4. Click Finish and activate the scheme when prompted.
  5. Set the extension's deployment target to match your main app (iOS 15.0 or later).

App Group

The main app and the Notification Service Extension must share data via an App Group.

Add App Group to main app target and Notification Service Extension
  1. Select the main app target in Xcode > Signing & Capabilities > + Capability > App Groups.
  2. Add the group you created earlier (e.g. group.com.yourcompany.yourapp).
  3. Repeat steps 1–2 for the Notification Service Extension target, using the same group identifier.

What to upload and configure in Twilio

  1. Return to your Twilio Notify Service in the Twilio Console.
  2. Under APN Credential, click Create new credential (or select an existing one).
  3. Paste the certificate from taguchi-push-twilio-cert.pem (including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).
  4. Paste the key from taguchi-push-twilio-rsa-key.pem.
  5. Select Sandbox if sending to a sandbox APNs environment.
  6. Save the credential and capture the APN Credential SID.
  7. Set that APN Credential SID on your Twilio Notify Service.

AppDelegate code configuration (React Native — additional vs. iOS-only)

Add the following code to AppDelegate.swift. React Native requires one additional function compared to a pure iOS app: application(_:open:options:) to handle deep links via RCTLinkingManager.

Note: Your app will need to request notification permission and tracking permission (App Tracking Transparency) at the correct stage of its lifecycle. When to prompt is up to the developer / company — for example (not limited to): at app launch, or after the user logs in. The SDK provides requestNotificationPermission() and requestTrackingPermission() for this (see API).

1. Conform to UNUserNotificationCenterDelegate

Update the AppDelegate class declaration to inherit UNUserNotificationCenterDelegate. This allows AppDelegate to receive notification-related callbacks from the system.

2. didRegisterForRemoteNotificationsWithDeviceToken

Called by the system after APNs successfully registers the device for push notifications. Converts the binary device token to a hex string and stores it in UserDefaults under the key DeviceToken so the SDK can read it later.

func application(_ application: UIApplication,
                didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenParts = deviceToken.map { String(format: "%02x", $0) }
    let token = tokenParts.joined()

    UserDefaults.standard.set(token, forKey: "DeviceToken")
    UserDefaults.standard.synchronize()

    // Optionally request tracking permission here
}

3. didFailToRegisterForRemoteNotificationsWithError

Called by the system when the system fails to register a device token. Handy for debugging.

func application(
    _ application: UIApplication,
    didFailToRegisterForRemoteNotificationsWithError error: Error
) {
    /// Some error occured while registering for device token
    /// Add logging as necessary
}

4. application(_:open:options:) (React Native only)

Called when the app is opened via a URL (for example, from a deep link in a notification). Delegates URL handling to React Native's RCTLinkingManager so the JS navigation layer can respond. This function is not required in a pure iOS (non-React Native) app.

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    return RCTLinkingManager.application(app, open: url, options: options)
}

5. application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

Called when a background or foreground remote notification is received. Passes the notification payload to TaguchimailPush so it can process delivery receipts and queue any in-app message data. Replace "group.com.company.appname" with your App Group identifier.

func application(
    _ application: UIApplication,
    didReceiveRemoteNotification userInfo: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
) {
    TaguchimailPush.handleDidReceiveRemoteNotification(userInfo: userInfo, applicationGroupIdentifier: "group.com.company.appname") {
        (data) in
        completionHandler(data)
    }
}

6. userNotificationCenter(_:didReceive:withCompletionHandler:)

Called when the user taps a notification or selects a custom action. Forwards the interaction to TaguchimailPush.performNotificationAction for Taguchi tracking, then calls completionHandler() to signal processing is complete.

func userNotificationCenter(
    _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void
) {
    TaguchimailPush.performNotificationAction(
        categoryIdentifier: response.notification.request.content.categoryIdentifier,
        actionIdentifier: response.actionIdentifier,
        userInfo: response.notification.request.content.userInfo
    )
    completionHandler()
}

7. userNotificationCenter(_:willPresent:withCompletionHandler:)

Called when the app is in foreground and the notification arrives.

func userNotificationCenter(
    _ center: UNUserNotificationCenter, willPresent notification: UNNotification,
    withCompletionHandler completionHandler:
        @escaping (UNNotificationPresentationOptions) -> Void
) {
    completionHandler([.badge, .sound, .banner])
}

Add target using Notification Service Extension template

The code should look like the following:

import TaguchimailPush
import UserNotifications

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(
        _ request: UNNotificationRequest,
        withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
    ) {
        self.contentHandler = contentHandler
        TaguchimailPush.handlePushNotificationServiceExtensionDidReceive(
            request, applicationGroupIdentifier: "group.com.company.appname") {
                (content) in
            self.bestAttemptContent = content
            contentHandler(self.bestAttemptContent!)
        }
    }

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

}

Other app configuration

  • Add the taguchimailpush package dependency to your Xcode project from either our repository or from a local copy.
  • Add taguchimailpush to both the App target and the Notification Service Extension target under App > General > Frameworks, Libraries, and Embedded Content.

  • Add a PrivacyInfo.xcprivacy file and complete the privacy nutrition label fields for any data your app collects.

  • Under App > Signing & Capabilities, add the User Notifications usage description to explain why the app requests notification permission.

  • Under App > Info > URL Types, add a URL scheme entry to enable deep link handling from notifications.

Push notification capabilities configured in XCode Push notification capabilities configured in XCode

Android pre-setup (React Native)

Android push notifications are delivered via Firebase Cloud Messaging (FCM). Complete the Firebase setup before modifying your Android project.

Create Project in Firebase

  1. Go to the Firebase Console.
  2. Click Add project, give it a name, and follow the prompts to create it.
Add Android app in Project Settings > General Tab
  1. Inside your Firebase project, click the Android icon (Add app).
  2. Enter your Android package name (must match your app's applicationId in build.gradle).
  3. Optionally enter a nickname and your SHA-1 debug certificate fingerprint.
  4. Click Register app.
  5. Download the google-services.json file when prompted.
Create service account in Google Cloud Console for Push
  1. Open the Google Cloud Console and select your Firebase project.
  2. Go to IAM & Admin > Service Accounts.
  3. Click + Create Service Account.
  4. Give the account the name notifications and click Create and Continue.
  5. Assign both roles:
    • Firebase Cloud Messaging Admin
    • Firebase Cloud Messaging API Admin
  6. Click Done.
  7. Click on the new service account, go to the Keys tab, and click Add Key > Create new key.
  8. Choose JSON and click Create. Download and store the key securely — you will upload this JSON key to Twilio as the FCM Secret Credential.

Firebase Dashboard Firebase Dashboard

Firebase - Add Android App Firebase - Add Android App

Google Cloud - Manage Service Accounts Google Cloud - Manage Service Accounts

What to upload and configure in Twilio

  1. Return to your Twilio Notify Service in the Twilio Console.
  2. Under FCM Credential, click Create new credential.
  3. Upload the JSON service account key file downloaded from Google Cloud Console.
  4. Save the credential and capture the FCM Credential SID.
  5. Set that FCM Credential SID on your Twilio Notify Service.

Mobile Push Credentials in Twilio Notify Mobile Push Credentials in Twilio Notify

Creating a new FCM Credential in Twilio Notify Creating a new FCM Credential in Twilio Notify

Android installation (React Native)

Add google-services.json to app folder

Copy the google-services.json file downloaded from Firebase into the android/app/ directory of your project:

your-project/
  android/
    app/
      google-services.json   ← place it here

Add dependencies to gradle files (React Native — Groovy format)

React Native projects typically use Groovy-format Gradle files. The configuration differs from a pure Android Kotlin DSL project.

Project-level /build.gradle.kts (plugins section):

buildscript {
    ...
    dependencies {
        ...
        classpath("com.google.gms:google-services:4.4.0")
    }
}

App-level /app/build.gradle:

apply plugin: "com.google.gms.google-services"

dependencies {
    implementation(platform("com.google.firebase:firebase-bom:34.7.0"))
    implementation("com.google.firebase:firebase-messaging")
    implementation(project(":taguchimailpushandroid"))
}

Add PushNotificationService.kt to your app

Create PushNotificationService.kt in your app

Location:

your-project/
  android/
    app/
      src/
        main/
          com/
            company/
              appname/
                PushNotificationService.kt   ← place it here

Code:

package com.company.appname

import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.taguchi.taguchimailpushandroid.TaguchimailPush


class PushNotificationService: FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        super.onNewToken(token)
        TaguchimailPush.storeDeviceToken(applicationContext, token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        TaguchimailPush.handleMessageReceived(this, message)
    }
}

Add taguchimailpushandroid library module to your project

The taguchimailpushandroid library module must be imported / placed at the project level. This contains the core SDK functionality.

your-project/
  android/
    taguchimailpushandroid/

Please see the code available in the repository.

Update AndroidManifest.xml

In /android/app/src/main/AndroidManifest.xml:

Inside <application> > <activity>, add an intent filter for deep link handling:

<intent-filter android:label="Deep Link">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="<deep-link-scheme>" />
</intent-filter>

Inside <application>, register the FCM messaging service:

<service android:name=".PushNotificationService" android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

React Native installation

Install the React Native SDK after completing the iOS and Android setup steps above.

Install library

Install the Taguchi React Native SDK from npm:

npm install taguchimail-mobile-sdk

For iOS, install the native dependencies via CocoaPods:

cd ios && pod install && cd ..

Set notification categories (optional, iOS)

Optionally, set up iOS notification categories (action buttons) in App.tsx using setNotificationCategories:

const iosNotificationCategories = [
    {
        identifier: 'EXAMPLE',
        actions: [
            { identifier: 'TEST1_ACTION', title: 'Test1' },
            { identifier: 'TEST2_ACTION', title: 'Test2' },
        ],
    },
];

useEffect(() => {
    setNotificationCategories(iosNotificationCategories);
}, []);

Add components (IAM)

To enable In-App Messaging, wrap your root application component with the InAppMessageView component — see In-App Messaging Usage below.

After completing React Native setup, proceed to Taguchi Credential and Integration Setup.

In-App Messaging Usage

To enable In-App Messaging, wrap your root application component with the InAppMessageView component:

import React from 'react';
import { InAppMessageView } from 'taguchimail-mobile-sdk';

const App = () => {
  return (
    <InAppMessageView applicationGroupIdentifier="group.com.yourcompany.yourapp">
      {/* Your app content */}
    </InAppMessageView>
  );
};

export default App;

The InAppMessageView component handles rendering of in-app messages. It should be placed at the root level so messages can appear over any screen.

API

Symbol Purpose
requestNotificationPermission() Requests notification permission (iOS prompt / Android POST_NOTIFICATIONS).
requestTrackingPermission() Requests App Tracking Transparency consent on iOS; resolves true on Android.
getDeviceToken() Returns the stored APNs / FCM device push token.
checkNotificationPermission() Returns current notification permission and tracking status.
getTrackingAuthorizationStatus() true when iOS ATT status is .authorized; always true on Android.
linkSubscriberToTaguchi(options) Links a device token to a subscriber profile via the Taguchi subscriber API. Accepts endpoint, deviceToken, subscriberTarget, subscriberIdentifier, and optional application and Android-only androidTrackingApproved override.
unlinkSubscriberToTaguchi(options) Removes a device-token binding from a subscriber profile.
fetchQueuedIAMResponse(applicationGroupIdentifier?) Fetches the queued in-app message payload without displaying or dequeuing it.
<InAppMessageView> Component that wraps your app and shows queued IAMs in a full-screen modal. Optional applicationGroupIdentifier prop (iOS App Group). Exposes show(), hide(), and await setIamUrl(url) via ref (InAppMessageViewRef).

Refer to the SDK README or TypeScript type definitions included with the package for the full API reference including parameter types and return values.

Taguchi Credential and Integration Setup

Once Twilio is configured and the SDK is installed, you need to link Twilio Notify to your Taguchi account.

Add Twilio credential for account

  1. Log in to Taguchi with an Administrator account.
  2. Navigate to Settings > Credentials.
  3. Click Add Credential and select Twilio as the credential type.
  4. Enter the following values from your Twilio account:
  5. Give the credential a descriptive name (e.g. Twilio Push) and save.

Add integrations to new Twilio Notify Service

Two separate integrations are required — one for push notifications and one for in-app messaging:

Integration Integration type
Push notifications pushnotification_twilio_notify
In-app messaging iam_twilio_notify

For each of the two integrations:

  1. Navigate to Settings > Integrations.
  2. Click Add Integration and select the integration type — Twilio Notify Push Notification (pushnotification_twilio_notify) for push notifications, or Twilio Notify In-App Messaging (iam_twilio_notify) for in-app messaging.
  3. Select the Twilio credential you created above.
  4. Enter the Notify Service SID noted during the Twilio setup step.
  5. Enter an Application value for your app. This is a unique identifier for the application of your choosing (for example taguchi-ice-cream) — it is not the app's bundle ID or Android package name. The same value must be used as the application value in each device's push binding (see Taguchi V5 API for Linking and Unlinking Device Tokens), and the same Application value should be used for both integrations.
  6. Save the integration.

Once both integrations are saved, Taguchi will route push notification and in-app messaging requests through your Twilio Notify Service.

Twilio Credential Setup Taguchi Credential Setup for Twilio

Taguchi Integrations page showing push and iam Taguchi Integrations

Taguchi V5 API for Linking and Unlinking Device Tokens

Device tokens must be registered with Taguchi to associate a subscriber profile with a specific device. In the V5 API this is managed in the Subscriber pushBindings property.

Note: The SDK also provides methods to link and unlink device tokens — see linkSubscriberToTaguchi(options) and unlinkSubscriberToTaguchi(options) in taguchimail-mobile-sdk (React Native), and the equivalent link/unlink helpers in TaguchimailPush (iOS) and TaguchimailPush (Android).

Important: Each push binding must include a valid application value that matches the Application value configured in a Twilio Notify integration in Taguchi (see Taguchi Credential and Integration Setup). The application value is not the app's bundle ID or Android package name — it is a unique identifier for the application, as set up in the integration. If the device's application value does not match an integration, the device cannot be targeted for push notifications or in-app messages.

Send a POST request to push a subscriber profile with a pushBindings entry:

POST https://{server}.taguchimail.com/apiv5_auth/{environment}/{endpoint-id}/subscriber

Request body:

[
  {
    "profile": {
      "email": "<email>",
      "pushBindings": [
        {
          "deviceToken": "<device-push-token>",
          "application": "<application-identifier>",
          "bindingType": "apn",
          "deviceType": "ios"
        }
      ]
    }
  }
]

Set bindingType to apn for iOS or fcm for Android. Set application to the unique application identifier configured in the Twilio Notify integration in Taguchi (not the app's bundle ID or package name).

To remove a device token association (for example when a user logs out), send a POST request with a matching pushBindings entry and "delete": true:

POST https://{server}.taguchimail.com/apiv5_auth/{environment}/{endpoint-id}/subscriber

Request body:

[
  {
    "profile": {
      "email": "<email>",
      "pushBindings": [
        {
          "deviceToken": "<device-push-token>",
          "application": "<application-identifier>",
          "bindingType": "fcm",
          "delete": true
        }
      ]
    }
  }
]

For full details on V5 API authentication and request structure, refer to the V5 API Documentation.

Device prioritization

When a subscriber has multiple linked devices, Taguchi uses device reach to decide which device(s) an activity should target. Device reach on activities can be configured to target:

  • Last active device
  • Last active device per platform
  • Last converted device

Device reach is attributed on a unique basis of application and device.

Device reach is set and updated as follows:

  1. When a device is added (either via the API or the SDK), last active device and last active device per platform are set for that device.
  2. An overnight process checks for any changes amongst subscriber events and updates the device reach for the push bindings set in Taguchi.

Tracking

Taguchi records tracking events for push notifications and in-app messages so you can report on delivery and engagement.

Important: Tracking must be turned on in the activity. If activity tracking is not enabled, tracking will not occur — only sent events will be recorded. In addition, engagement events (open, view, click and analytics) require the user to have approved app tracking on their device (see requestTrackingPermission() in taguchimail-mobile-sdk (React Native)).

Push notification events

Event Code When it occurs Recorded
Sent s When the push notification is sent from Taguchi (not deliverability) Always
Open o When the notification is received on the user's device Only if activity tracking is on and app tracking is approved
Analytics wa App interactions — clicking the notification, or clicking a notification button Only if activity tracking is on and app tracking is approved

In-app messaging events

Event Code When it occurs Recorded
Sent s When the in-app message is sent from Taguchi (not deliverability) Always
View v When the in-app message opens and is shown to the user Only if activity tracking is on and app tracking is approved
Click c When the subscriber clicks and navigates to a webpage Only if activity tracking is on and app tracking is approved
Analytics wa App interactions — clicking a deeplink, or copying a value to the clipboard Only if activity tracking is on and app tracking is approved

Event flow

The diagram below shows when each event is logged for push notifications and in-app messages:

Event flow diagram showing when sent, open, view, click and analytics events are logged for push notifications and in-app messages

FAQ / Limitations / What to be careful about

General

Q: Do I need a separate Twilio Notify Service for iOS and Android?

No. A single Twilio Notify Service can hold both an APNs credential (for iOS) and an FCM credential (for Android). (GCM is deprecated)

Q: Are in-app messages (IAM) delivered via push notifications?

Yes. In-App messages are delivered using silent notifications to pre-download, so that they are ready to be presented to the user.

Limitations

  • Delivery is not guaranteed to be immediate: Push notifications and in-app messages may not arrive immediately after they are sent. Network conditions, device state, and operating system behavior can delay delivery. Apple Push Notification service (APNs) and Firebase Cloud Messaging (FCM) are best-effort delivery services and may delay or throttle notifications under certain conditions. Do not rely on push notifications or in-app messages for time-critical delivery guarantees.
  • iOS simulator: Push notifications cannot be received on the iOS Simulator. You must test on a physical iOS device.
  • Background message handling: On iOS, background data-only messages require the Remote notifications background mode to be enabled. Foreground notifications are handled differently and may require additional configuration in your AppDelegate.
  • Token refresh: Device push tokens can change (e.g. after app reinstall or OS update). Ensure your app links device token to a Taguchi subscriber each time it receives a new token from the platform (APNs or FCM) and unlinks stale tokens to avoid delivery failures.
  • Android 13+ notification permission: Android 13 (API 33) and above require explicit user permission to display notifications. Ensure you request the POST_NOTIFICATIONS permission at runtime.
  • Twilio Notify Service SID: The Notify Service SID is fixed after initial setup. If you need to change services, you must update both the Taguchi integration and all client-side SDK configurations.
  • Certificate expiry (iOS): APNs push certificates expire annually. Monitor expiry dates and renew before they lapse to avoid notification delivery failures.
  • FCM service account key rotation: If you rotate the Google Cloud service account key, you must update the FCM credential in Twilio and re-upload the new JSON key file.

Troubleshooting

Notifications not received on iOS:

  • Verify the .pem files were generated from the correct certificate (production vs. sandbox).
  • Confirm the Push Notifications capability is enabled for your App ID in the Apple Developer Portal.
  • Check that the Notification Service Extension has the same App Group as the main target.
  • Ensure you are testing on a physical device, not the simulator.
  • Ensure you have an Apple Developer Account.

Notifications not received on Android:

  • Verify google-services.json is in the android/app/ directory and matches the Firebase project.
  • Confirm the FCM credential in Twilio was created with a valid service account JSON key.
  • Check that Gradle is configured correctly.

If problems persist, contact Taguchi Support.