# Swift SDK

Bird Swift SDK is a single integration point to bring the power of BirdCRM in building connected user experience to your application.

Using Bird Swift SDK, you get access to:

* Collect Contacts
* Send Push Notifications

Integrating Bird Swift SDK into your application consists of the following steps:

* Step 1: Add Bird Swift SDK dependency
* Step 2: Set Application Key, App Group & Keychain Group
* Step 3: Add Capabilities
* Step 4: Create AppDelegate
* Step 5: Create Notification Service Extension
* Step 6: Create Notification Content Extension
* Step 7: Create App Group & Keychain Group

## Step 1: Add Bird Swift SDK dependency

You can add Bird Swift SDK as a dependency to your project using Swift Package Manager

1. In your application in Xcode. Go to **File** > **Add Packages Dependencies** to add a new dependency.
2. Specify the URL of the Bird Swift SDK <https://github.com/messagebird/swift-sdk>.
3. Select the `swift-sdk` package and click "Add Package"

## Step 2: Set Application Key,  App Group & Keychain group

All configuration for Bird Swift SDK can be set up in `Info.plist` file in your application.

1. Inside `Info.list` file, add an entry for `Bird` with type `Dictionary`.
2. Then add the following fields with type `String` inside the `Bird` dictionary
   * **ApplicationKey**: You can get the value of this application key from "**Bird Dashboard / Preferences / Applications**".&#x20;
   * **AppGroup**: This is the name of the app group you will create in [Step 7: Create App Group & Keychain Group](#step-7-create-app-group).
   * **AccessGroup**: This is a name of the access group for keychain sharing you will create in  [Step 7: Create App Group & Keychain Group](#step-7-create-app-group). Usually it has the following format: `{TEAM_ID}.{KEYCHAIN_GROUP}`.&#x20;

`Info.plist` should look like this:

<figure><img src="https://3210271997-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdnJZeZvhOMhDQA8SpjQM%2Fuploads%2F5IhYx7LFftuG5guAWx3w%2FScreenshot%202024-06-24%20at%2012.52.15.png?alt=media&#x26;token=a0f1bcb7-8429-45eb-b47f-53340abb9c8e" alt=""><figcaption></figcaption></figure>

These values need to be added to the `Info.plist` file for each of the following:

* The iOS application target
* Notification Service Extension target. See [Step 5: Create Notification Service Extension](#step-5-create-notification-service-extension).&#x20;
* Notification Content Extension target. See [Step 6: Create Notification Content Extension](#step-6-create-notification-content-extension)

## Step 3: Add Capabilities

Open your application project in XCode.

* Select your project in XCode
* Select the target of your project under `TARGETS`
* Go to `Signing and Capabilities` tab
* Click on `+ Capability` and add the following Capabilities:
  * Push Notifications
  * Background Modes
* From `Background Modes` section, select `Remote notifications`

## Step 4: Create AppDelegate

You may already have an AppDelegate. If not, you need to create one like in the example below.

Notice that:

* instance of `Bird` is created once and saved in a static member
* `bird.notifications.registerDevice` is called inside the method with argument `didRegisterForRemoteNotificationsWithDeviceToken`
* `bird.notifications.applicationDidReceiveRemoteNotification` is called inside the method with argument `didReceiveRemoteNotification`
* `bird.notifications.willPresentNotification` and  `bird.notifications.didReceiveResponse(response)` are called from the corresponding methods of `UNUserNotificationCenterDelegate`

```swift
class AppDelegate: NSObject, UIApplicationDelegate {
    static var bird: Bird!
    static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "AppDelegate")
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        do {
            AppDelegate.bird = try Bird()
        } catch {
            Self.logger.log("failed to create bird")
        }
        
        UNUserNotificationCenter.current().delegate = self
        return true
    }
    
    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Self.bird.notifications.registerDevice(deviceToken: deviceToken) 
    }
    
    func application(
        _ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable : Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        Self.bird.notifications.handleBackgroundNotification(
            userInfo: userInfo, 
            completionHandler: completionHandler
        )
    }
    
    // Call this method to request notifications permissions
    static func requestNotificationsPermission() {
        UNUserNotificationCenter.current().requestAuthorization(
            options:[.badge, .alert, .sound]
        ) { granted, error in
            guard granted else {
                self.logger.log("Notification permission is not gratned")
                return
            }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        let options = Self.bird.notifications.willPresentNotification(notification)
        completionHandler(options)
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        let result = Self.bird?.notifications.handleNotificationResponse(
            response: response,
            automaticallyOpenLinks: true
        )
        completionHandler()
    }
}
```

Then you need to use this class as your application delegate. In case you use Swift UI, here is an example:

```swift
import SwiftUI

@main 
struct DemoApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

## Step 5: Create Notification Service Extension

Add a Notification Service Extension to your project.

1. Select **File** > **New** > **Target** in Xcode.
2. Select the **Notification Service Extension** target from the iOS > Application section.
3. Click **Next**.
4. Specify a name and other configuration details for your app extension.
5. Click **Finish**.

Then change the code in NotificationService.swift to only extend from `BirdNotificationService` as follows:

```swift
import BirdKit

class NotificationService: BirdNotificationService {
}
```

Remember to add `Bird` configuration to `Info.plist` of Notification Service Extension target as explained in [Step 2: Set Application Key, App Group & Keychain group](#step-2-set-application-key-and-app-group).

## Step 6: Create Notification Content Extension

Add a Notification Content App Extension to Your Project

1. Select **File** > **New** > **Target** in Xcode.
2. Select **Notification Content Extension** from iOS Application Extension.
3. Click **Next**.
4. Provide a name for your app extension.
5. Click **Finish**.

Then go ahead and do the following steps:

1. Remove the storyboard file from the extension
2. Remove the `NSExtensionMainStoryboard` entry from the extension's Info.plist.
3. Add a new entry of `NSExtensionPrincipalClass` to the Info.plist under `NSExtension`. The value should be `$(PRODUCT_MODULE_NAME).NotificationViewController`
4. Change the value for entry `UNNotificationExtensionCategory` to be `BIRD`
5. Change `NotificationViewController.swift` to only extend `BirdNotificationViewController` as follows:

```swift
import BirdKit

class NotificationViewController: BirdNotificationViewController {
}
```

Remember to add `Bird` configuration to `Info.plist` of Notification Content Extension target as explained in [Step 2: Set Application Key & App Group](#step-2-set-application-key-and-app-group).

## Step 7: Create App Group and Keychain sharing

1. Select your project in XCode
2. Select the target application of your project under `TARGETS`
3. Go to `Signing and Capabilities` tab
4. Click on `+ Capability` and add the following Capabilities:
   * App Groups
   * Background Modes
   * Keychain sharing
5. Inside `App Groups` section:
   * add a new App Group if needed
   * Select an App Group for this target
6. Inside `Keychain Sharing` section:&#x20;
   * Add a new Keychain Group (usually it has the same equals to bundle id of the main target of the app)
7. Do the same process of adding App Groups and select the same App Group for:
   * Notification Service Extension target
   * Notification Content Extension target

The go ahead and add the `AppGroup` and `AccessGroup` to the `Info.plist` as explained in [Step 2: Set Application Key, App Group & Keychain Group](#step-2-set-application-key-app-group-and-keychain-group) for each of the following:

* The iOS application target
* Notification Service Extension target
* Notification Content Extension target

## Examples

You can find examples and report issue on the public repository [messagebird/swift-sdk](https://github.com/messagebird/swift-sdk).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.bird.com/api/client-sdks/sdk-integration/swift-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
