# Upgrade from 2x to 3x

 There's a new version available!

These pages cover version 3 of our SDK, but a newer version is available. In general, we suggest that you update to the latest version to take advantage of new features and fixes.

*   Are you new to our SDKs? [Check out the latest docs.](/integrations/sdk/ios/getting-started)
*   Otherwise, [learn about updating to the latest version](/integrations/sdk/ios/whats-new/)

This page details breaking changes from the previous major version of the SDK, so you understand the development effort required to update your app and take advantage of the latest features.

## What changed?[](#what-changed)

This update provides native support for our new integrations framework. While this represents a significant change “under the hood,” we’ve tried to make it as seamless as possible for you; much of your implementation remains the same.

This move also adds two additional features:

*   **Support for anonymous tracking**: you can send events and other activity for anonymous users, and we’ll reconcile that activity with a person when you identify them.
*   **Built-in lifecycle events**: the SDK now automatically captures events like “Application Installed” and “Application Updated” for you.
*   **New device-level data**: the SDK captures the device `name` and other device-level context for you.

## Upgrade process[](#upgrade-process)

You’ll update initialization calls for the SDK, the in-app messaging module, and the push module. The in-app and push modules are now required.

**As a part of this process, your credentials change**. You’ll need to set up a new data inAn integration that feeds data *into* Customer.io. integration in Customer.io and get a new *CDP API Key*. But you’ll *also* need to keep your previous `siteId` as a `migrationSiteId` when you initialize the SDK. The `migrationSiteId` is a key helps the SDK send remaining traffic when people update your app.

When you’re done, you’ll also need to change a few base properties to fit the new APIs. In general, `identifier` becomes `userId`, `body` becomes `traits`, and `data` becomes `properties`.

### 1\. Get your new *CDP API Key*[](#1-get-your-new-cdp-api-key)

The new version of the SDK requires you to set up a new data inAn integration that feeds data *into* Customer.io. integration in Customer.io. As a part of this process, you’ll get your *CDP API Key*.

1.  Go to [*Data & Integrations* > *Integrations*](https://fly.customer.io/workspaces/last/journeys/integrations/all/overview) and click **Add Integration**.
2.  Select **iOS**.
    
    [![set up your iOS source](https://docs.customer.io/images/cdp-ios-source.png)](#67f0591daae0ccd9a402e4bfcb137c78-lightbox)
    
3.  Enter a *Name* for your integration, like “My iOS App”.
4.  We’ll present you with a `cdpApiKey` that you’ll use to initialize the SDK. Copy this key and keep it handy.
5.  Click **Complete Setup** to finish setting up your integration.
    
    [![Set your name, get your CDP API Key, and click Complete Setup](https://docs.customer.io/images/cdp-ios-source-setup.png)](#be5c9653f8ae715bc7a9a87b2729f76c-lightbox)
    

Remember, you can also [connect your iOS app to services outside of Customer.io](/integrations/data-out/add-destination/)—like your analytics provider, data warehouse, or CRM.

### 2\. Import CioDataPipelines instead of CioTracking[](#2-import-ciodatapipelines-instead-of-ciotracking)

We’ve replaced the `CioTracking` package with `CioDataPipelines`. You’ll need to update your import statements to reflect this change.

If you see errors like *Missing required module ‘CioTracking’*, you can remove the package in XCode under *Frameworks and Libraries*.

```swift
// replace import CioTracking with:
import CioDataPipelines
```

### 3\. Update your `initialize` calls[](#3-update-your-initialize-calls)

You’ll initialize the new version of the SDK and its packages with `SDKConfigBuilder` objects instead of a `CustomerIOConfig`. A few of the configuration options changed. In particular,

*   `cdpApiKey` replaces `apiKey`: this is a new key that you got from [Step 1](#1-get-your-new-cdp-api-key)
*   `migrationSiteId` replaces `siteId`: this is the same key you used in the previous version of the SDK. **You need to include this property** to send remaining traffic when people update your app.
*   `autoTrackUIKitScreenViews` replaces `autoTrackScreenViews`: functionality is unchanged; we simply renamed the option to reflect support for UIKit and *not* SwiftUI.
*   **If you’re in our EU region**, make sure that you uncomment the `.region(.EU)` line in the sample below. Your config must include this property to send data to our EU data center.

 APNS

#### APNS[](#APNS)

```swift
import CioDataPipelines
import CioMessagingInApp
import CioMessagingPushAPN
import UIKit

@main
// Add the CioAppDelegateWrapper to handle push notifications and device token registration
class AppDelegateWithCioIntegration: CioAppDelegateWrapper<AppDelegate> {}

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        let cdpApiKey = YOUR_CDP_API_KEY
        let siteId = YOUR_SITE_ID
        
        let config = SDKConfigBuilder(cdpApiKey: cdpApiKey)
            // uncomment the line below if your account is in the EU region
            // .region(.EU)
            .autoTrackDeviceAttributes(true)
            .migrationSiteId(siteId)
            //replaces autoTrackScreenViews
            .autoTrackUIKitScreenViews()

        CustomerIO.initialize(withConfig: config.build())

        // Initialize messaging features after initializing Customer.io SDK
        MessagingInApp
            .initialize(withConfig: MessagingInAppConfigBuilder(siteId: siteId, region: .US).build())
            .setEventListener(self)
        MessagingPushAPN.initialize(
            withConfig: MessagingPushConfigBuilder()
                .autoFetchDeviceToken(true)    // Automatically fetch device token and upload to CustomerIO
                .autoTrackPushEvents(true)     // Automatically track push metrics
                .showPushAppInForeground(true) // Enable Notifications in the foreground
                .build()
        )
      
        UNUserNotificationCenter.current().delegate = self

        return true
    }   
```

 FCM

#### FCM[](#FCM)

```swift
import CioDataPipelines
import CioMessagingInApp
import CioMessagingPushFCM
import FirebaseCore
import FirebaseMessaging
import Foundation
import UIKit

@main
// Add the CioAppDelegateWrapper to handle push notifications and device token registration
class AppDelegateWithCioIntegration: CioAppDelegateWrapper<AppDelegate> {}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        // To set up FCM push: https://firebase.google.com/docs/cloud-messaging/ios/client
        // FCM provides a device token to the app that
        // you send to the Customer.io SDK.

        // Initialize the Firebase SDK.
        FirebaseApp.configure()

        let siteId = YOUR_JOURNEYS_SITE_ID
        let cdpApiKey = YOUR_CDP_API_KEY

        // Configure and initialize the Customer.io SDK
        let config = SDKConfigBuilder(cdpApiKey: cdpApiKey)
            // uncomment this line below if your account is in the EU region
            // .region(.EU)
            .migrationSiteId(siteId)
            .autoTrackDeviceAttributes(true)
            //replaces autoTrackScreenViews
            .autoTrackUIKitScreenViews()

  
        CustomerIO.initialize(withConfig: config.build())

        // Initialize messaging features after initializing Customer.io SDK
        MessagingInApp
            .initialize(withConfig: MessagingInAppConfigBuilder(siteId: siteId, region: .US).build())
            .setEventListener(self)
        MessagingPushFCM.initialize(
            withConfig: MessagingPushConfigBuilder()
                .autoFetchDeviceToken(true)    // Automatically fetch device token and upload to CustomerIO
                .autoTrackPushEvents(true)     // Automatically track push metrics
                .showPushAppInForeground(true) // Enable Notifications in the foreground
                .build()
        )

        // Manually get FCM device token. Then, we will forward to the Customer.io SDK.
        Messaging.messaging().delegate = self

        UNUserNotificationCenter.current().delegate = self

        return true
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
    }
}
```

### 4\. Update your `NotificationServiceExtension`[](#4-update-your-notificationserviceextension)

You need to initialize the push module with your integration’s *CDP API Key*. Update your `NotificationServiceExtension` (using the appropriate push package, APN or FCM).

If you previously initialized the SDK using `CustomerIO.initialize`, you can remove that now. You *only* need to initialize the push package.

```swift
// use MessagingPushFCM if FCM is your push service
MessagingPushAPN.initializeForExtension(
  withConfig: MessagingPushConfigBuilder(
      cdpApiKey: "YOUR_CDP_API_KEY"
  )
  // Optional: set your Customer.io account region (.US or .EU). Default: US
  .region(.US)
  .build()
)
```

### 5\. Update your `identify`, `track`, and `screen` calls[](#5-update-your-identify-track-and-screen-calls)

Our APIs changed slightly in this release. We’ve done our best to make the new APIs as similar as possible to the old ones. The names of a few properties that you’ll pass in your calls have changed, but their functionality has not.

*   `identify`: `identifier` becomes `userId` and `body` becomes `traits`
*   `track`: `data` becomes `properties`
*   `screen`: `name` becomes `title`, and `data` becomes `properties`

 New (3.x)

#### New (3.x)[](#New \(3.x\))

```swift
// CioDataPipelines replaces CioTracking 
import CioDataPipelines
//identify: identifier becomes userId, body becomes traits
CustomerIO.shared.identify(userId: "USER_ID", traits: ["age": 30])

// track: data becomes properties
CustomerIO.shared.track(name: "Purchase", properties: ["product": "shirt"])

// screen: name becomes title, data becomes properties
CustomerIO.shared.track(title: "Cart", properties: ["source": "link"])
```

 Old (2.x)

#### Old (2.x)[](#Old \(2.x\))

```swift
import CioTracking

// identify
CustomerIO.shared.identify(identifier: "USER_ID", body: ["age": 30]) {}

// track
CustomerIO.shared.track(name: "Purchase", data: ["product": "shirt"])

// screen
CustomerIO.shared.track(name: "Cart", data: ["source": "link"])
```

## Configuration Changes[](#configuration-changes)

As a part of this release, we’ve changed a few configuration options. The `MessagingInApp` and `MessagingPush` modules also now take their own configuration options.

### `DataPipelines` configuration options[](#datapipelines-configuration-options)

For the base SDK, you’ll use `SDKConfigBuilder` to set your configuration options. The following table shows the changes to the configuration options.

Field

Type

Default

Description

`cdpApiKey`

string

Replaces `apiKey`; required to initialize the SDK and send data into Customer.io.

`migrationSiteId`

string

Replaces `siteId`; required if you’re updating from 2.x. This is the key representing your previous version of the SDK.

`autoTrackUIKitScreenViews`

boolean

`false`

Replaces `autoTrackScreenViews`; functionality is unchanged. We simply renamed the option to reflect support for UIKit and *not* SwiftUI.

`trackApplicationLifeCycleEvents`

boolean

`true`

When true, the SDK automatically tracks application lifecycle events (like *Application Installed*).

### `MessagingPush` configuration options[](#messagingpush-configuration-options)

You need to initialize the push package in both your `AppDelegate` and `NotificationServiceExtension` files. In your `AppDelegate`, you don’t need to pass options. You can simply pass `MessagingPushAPN.initialize()`.

But, in your `NotificationServiceExtension`, you’ll need to pass the `cdpApiKey` to initialize the push package.

```swift
MessagingPushAPN.initializeForExtension(withConfig: MessagingPushConfigBuilder(cdpApiKey: "CDP_API_KEY").build())
```

Option

Type

Default

Description

`region`

`.US` or `.EU`

`.US`

The region your Customer.io account resides in US or EU.

`autoFetchDeviceToken`

boolean

`true`

When `true`, the package automatically fetches the device token for push notifications.

`autoTrackPushEvents`

boolean

`true`

Automatically track `opened` and `delivered` metrics based on push notifications.

`showPushAppInForeground`

boolean

`true`

Show push notifications when the app is in the foreground. Used only if customer’s AppDelegate doesn’t implement `UNUserNotificationCenterDelegate`.

### `MessagingInApp` configuration options[](#messaginginapp-configuration-options)

When you initialize the `CioMessagingInApp` package, **you must pass both of these configuration options**.

Option

Type

Default

Description

`siteId`

string

The [Site IDEquivalent to the *user name* you’ll use to interface with the Journeys Track API; also used with our JavaScript snippets. You can find your Site ID under *Workspace Settings* > *API Credentials*](https://fly.customer.io/env/last/settings/api_credentials) from a set of Track API credentials; this determines the workspace that your app listens for in-app messages from.

`Region`

`.US` or `.EU`

`.US`

The region your Customer.io account resides in—US or EU.