> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://fyno.io/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://fyno.io/docs/_mcp/server.

# Swift Push SDK

> Integrate native iOS remote push capabilities into your mobile applications. Build robust pipelines for APNs, Firebase Cloud Messaging, and background delivery tracking.

Fyno's iOS (Swift) Push Notification SDK offers a comprehensive set of notification features within your app. It's designed to efficiently deliver messages, ensuring optimal performance and user experience.

## Prerequisites

In order to get started, there are a few prerequisites that needs to be in place:

* **Fyno account:** A valid Fyno workspace with at least one active API Key. For more info, refer [Workspace Docs](./workspace-settings).
* **Configuration:** Configure your Fyno Push provider in Fyno App > [Integrations](https://app.fyno.io/integrations).
* **Swift iOS application:** A working Swift iOS application in which you want to integrate the SDK.
* **Apple developer account:** Required details are mentioned in [APNs Docs](./push-apns).

## Installation

### Install the SDK

Add `pod 'fyno-push-ios', '~> 1.1'` similar to the following to your `Podfile`:

**`Podfile`**

```Text title="Podfile" wordWrap
target 'MyApp' do
  pod 'fyno-push-ios', '~> 1.1'
end
```

Then run a pod install inside your terminal to download and install the fyno push sdk for iOS.

### Add Required Capabilities

1. Inside Targets select signing and capabilities.

2. Click on +capabilities and add Push Notifications and Background Modes capabilities to your application.
   ![](/docs/_fern-img/b07197bd5747b13db3c5d92dc01bb83e27db569c52b297b230c6d8dbdd0a78cc.webp)
   ![](/docs/_fern-img/9941335ebf01ee95bd9aaefa9ffe581cd92643e2d1be85103218b0055f6fe4f1.webp)

3. In Background Modes, select Remote Notifications option. We use background notifications to receive delivery reports when your app is in quit and background state. Refer [doc](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app) to know more about background notifications.
   ![](/docs/_fern-img/bf1d2342af83afd1d92e3dc5e9edddbe8be27112f63e2f555c680d91a2d66105.webp)

### Add Notification Service Extension to your application

1. In Xcode go to **File** > **New** > **Target**.

2. Select `Notification Service Extension` from the template list.

3. Then in Next popup give it any product name, select your team, select swift language and click finish.
   ![](/docs/_fern-img/92630a28cf4d0752f8abc1ed64d05ca481271f8123b573806fc4ed24dcd6790c.webp)
   ![](/docs/_fern-img/d821f8e0a40ab13c4783f1494bd29e26c9e947217c95469f3ac5f927c7da1c3f.webp)

4. After clicking on "Finish", a folder will be created with your given product name. Replace the contents of the **NotificationService.swift** file with the below code.

   **`NotificationService.swift`**

   ```swift title="NotificationService.swift" wordWrap
   import UserNotifications
   import UIKit
   import fyno

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

       override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
           fyno.app.handleDidReceive(request, withContentHandler: contentHandler)
       }

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

5. In order for the **Notification Service Extension** to be able to access the fyno SDK, you will have to import it by following the below steps:
   ![](/docs/_fern-img/4cce26d5c8ba1261f89094ffd9824559b257e29bf70d1cd95f9e2f23150c1a49.webp)
   ![](/docs/_fern-img/aaa07ea4b31dc9986263368ec5173d68a00aa396d4f45434a82a07302438981c.webp)

6. Search for `https://github.com/fynoio/ios-sdk` in the text box. Select and add the package named **ios-sdk**.
   ![](/docs/_fern-img/6603d6a9dd1a52cfda7656f5732557dd58bb6c81b0888dc376ea3d1e69807ca9.webp)

7. Select the Target as the Notification Service Extension you had created and click on `Add Package`.
   ![](/docs/_fern-img/6bc395a2611392af878e198f927d9766fde40984df09ded6570c91ea74ef8667.webp)

> **Tip**
>
> If you face any build issues similar to `Error (Xcode): Cycle inside Runner; building could produce unreliable results` after adding the notification service extension, follow [this](https://stackoverflow.com/a/77261331) answer to resolve it.

### Register for push notification in AppDelegate.swift file

Add the below code in your `AppDelegate.swift` file.

**`Without FCM`**

```swift title="Without FCM" wordWrap
// without FCM

import Foundation
import UIKit
import fyno_push_ios

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
let fynosdk = fyno.app

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

       self.fynosdk.registerForRemoteNotifications()
       fynosdk.requestNotificationAuthorization{ _ in}

       return true
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Send the device token to fynoServer
        fynosdk.setdeviceToken(deviceToken: deviceToken)
    }

}

```

**`With FCM`**

```swift title="With FCM" wordWrap
// with FCM

import Foundation
import UIKit
import fyno_push_ios

// imports required for FCM integration
import FirebaseCore
import FirebaseMessaging

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate  {
    let fynosdk = fyno.app

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

       self.fynosdk.registerForRemoteNotifications()

       FirebaseApp.configure() // add only if FCM has been integrated

       fynosdk.requestNotificationAuthorization{ _ in}

       return true
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Send the device token to fynoServer
        fynosdk.setdeviceToken(deviceToken: deviceToken)

        Messaging.messaging().apnsToken = deviceToken // add only if FCM has been integrated
    }
}
```

> **Success**
>
> You have successfully configured the iOS SDK for receiving push notifications.

## Usage

### Initialising the SDK (to be called on app launch)

To initialise the Fyno SDK, you need to provide the following information:

* **Workspace ID (Mandatory):** Your unique Fyno workspace ID, available on the Fyno App > [Workspace Settings](https://app.fyno.io/settings) page.
* **Integration ID (Mandatory):** The ID of the integration created in Fyno App > [Integrations](https://app.fyno.io/integrations).
* **Distinct ID (Optional):** A unique identifier for your user. If not provided, a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) is automatically generated.
* **Version (Optional):** Indicates the environment in which the user has to be created. Default is **"live"**, but you can set it to **"test"** for testing purposes.

**`swift`**

```swift title="swift" wordWrap
fyno.app.initializeApp(
    workspaceID: workspaceId,
    integrationID: integrationID,
    distinctId: distinctID,
    version: version
){
    initResult in
    switch initResult {
    case .success(_):
        print("Initialization successful")
    case .failure(let error):
        print(error)
    }
}
```

### Identifying the User

To update/set a distinct ID or user name, call `fyno.app.identify()`.

* **Distinct ID (Mandatory):** The distinct ID you want to identify the user with.
* **User Name (Optional):** - The name you want to assign to the user.

**`swift`**

```swift title="swift" wordWrap
fyno.app.identify(newDistinctId: distinctID, userName: userName) { identifyResult in
    switch identifyResult{
    case .success(_):
        print("Identify successful")
    case .failure(let error):
        print(error)
    }
}
```

### Registering for Push Notifications

To register the application for push notifications, call `fyno.app.registerPush()`.

* **isAPNs (Mandatory):** Use **true** if [APNs](./push-apns) is configured, **false** if [Google FCM](./push-fcm) is configured in the integration.

**`swift`**

```swift title="swift" wordWrap
fyno.app.registerPush(isAPNs: isAPNs){
    registerPushResult in
    switch registerPushResult{
    case .success(_):
        print("registerPush successful")
    case .failure(let error):
        print(error)
    }
}
```

### Merging User Profiles

If you need to merge two user profiles, call `fyno.app.mergeProfile()` with the old and new distinct IDs.

**`swift`**

```swift title="swift" wordWrap
fyno.app.mergeProfile(newDistinctId:newDistinctId){
    mergeResult in
    switch mergeResult{
    case .success(_):
        print("mergeProfile successful")
    case .failure(let error):
        print(error)
    }
}
```

### Updating Message Status

You can update the status of a notification (received, clicked or dismissed) using `fyno.app.updateStatus()`.

* **Callback URL (Mandatory):** You can obtain the Callback URL from the notification additional payload if the notification was triggered from Fyno.
* **Status (Mandatory):** The status of the notification (one of **RECEIVED**, **CLICKED** or **DISMISSED**).

**`swift`**

```swift title="swift" wordWrap
fyno.app.updateStatus(callbackUrl: callbackUrl, status: status){
    updateStatusResult in
    switch updateStatusResult{
    case .success(_):
        print("updateStatus successful")
    case .failure(let error):
        print(error)
    }
}
```

### Resetting User Information

To reset user information, call `fyno.app.resetUser()`.

* You can invoke this function when the user logs out of the application.
* It handles the deletion of channel data associated with the current user, initiates the creation of a fresh user profile, and transfers this particular channel data (push token) to the newly created profile.
* This feature proves to be invaluable if you plan to send push notifications to an application even after the user has logged out.
* It is also **recommmended** as it ensures that devices where the users have logged out are no longer associated with them.

**`swift`**

```swift title="swift" wordWrap
fyno.app.resetUser() {
    resetUserResult in
    switch resetUserResult{
    case .success(_):
        print("resetUser successful")
    case .failure(let error):
        print(error)
    }
}
```