On this page

iOS SDK Migration Guide

The new version of Amplitude's iOS SDK (Amplitude-Swift) offers a plugin architecture, built-in type definitions, and broader support for front-end frameworks. The new version isn't backward compatible with Amplitude-iOS.

To migrate to Amplitude-Swift, update your dependencies and instrumentation.

Terminology

  • Amplitude-iOS: maintenance iOS SDK.
  • Amplitude-Swift: new iOS SDK.

Dependencies

Add AmplitudeSwift dependency to Podfile.

diff
- pod 'Amplitude', '~> 8.14'
+ pod 'AmplitudeSwift', '~> 1.0'

Instrumentation changes

This SDK offers an API to instrument events. To migrate to the new SDK, update a few calls. The following sections detail which calls changed.

Initialize the SDK

Amplitude-Swift removes instance() along with the other calls. The new iOS SDK uses the Configuration object to set configuration values.

swift
import Amplitude
import AmplitudeSwift

Amplitude.instance().trackingSessionEvents = true
Amplitude.instance().initializeApiKey("YOUR-API-KEY")
let amplitude = Amplitude(configuration: Configuration(
    apiKey: "API_KEY",
    autocapture: [.sessions, .appLifecycles, .screenViews, .networkTracking]
))

Configure the SDK

Track events

The maintenance iOS SDK offered several logEvent APIs with withEventProperties, withApiProperties, withUserProperties, withGroup, withGroupProperties, withTimestamp, and outOfSession to override specific properties in the event payload. Amplitude consolidates these variations into a unified track API.

logEvent

The logEvent() API maps to track().

swift
let eventType = "Button Clicked"
let eventProperties: [String: Any] = ["key": "value"]

Amplitude.instance().logEvent(
 eventType,
 withEventProperties: eventProperties
)
let event = BaseEvent(
  eventType: eventType,
  eventProperties: eventProperties
)
amplitude.track(event)

logEvent withTimestamp

The logEvent() API maps to track().

swift
let eventType = "Button Clicked"
let timestamp = Int64(NSDate().timeIntervalSince1970 * 1000)
Amplitude.instance().logEvent(
 eventType,
 withTimestamp: timestamp
)
let event = BaseEvent(
  eventType: eventType,
  timestamp: timestamp
)
amplitude.track(event)

logEvent withGroup

The logEvent() API maps to track().

swift
let eventType = "Button Clicked"
let eventProperties: [String: Any] = ["key": "value"]
let groups: [String: Any] = ["orgId": 10]

Amplitude.instance().logEvent(
 eventType,
 withEventProperties: eventProperties,
 withGroups: groups
)
let event = BaseEvent(
  eventType: eventType,
  eventProperties: eventProperties,
  groups: groups
)
amplitude.track(event)

uploadEvents

The uploadEvents() API maps to flush().

swift
Amplitude.instance().uploadEvents()
amplitude.flush()

Set user properties

The APIs for setting user properties are the same, except that Amplitude-Swift removes instance(). The following code snippets show how to migrate user property APIs.

setUserId

ID length limit

The maintenance SDK uses an old SDK endpoint (api2.amplitude.com) that enforces no length limit for deviceId and userId. The latest SDK uses Amplitude's HTTP V2 API (api2.amplitude.com/2/httpapi) and requires identifiers of at least 5 characters by default. When you migrate to the latest SDK, set config.minIdLength to a smaller value if you allowed identifiers shorter than 5 characters.

Set a user ID on amplitude without calling getInstance().

swift
let userId = "TEST-USER-ID"
Amplitude.instance().setUserId(userId)
amplitude.setUserId(userId: userId)

setDeviceId

ID length limit

The maintenance SDK uses an old SDK endpoint (api2.amplitude.com) that enforces no length limit for deviceId and userId. The latest SDK uses Amplitude's HTTP V2 API (api2.amplitude.com/2/httpapi) and requires identifiers of at least 5 characters by default. When you migrate to the latest SDK, set config.minIdLength to a smaller value if you allowed identifiers shorter than 5 characters.

Set a device ID on amplitude without calling instance().

swift
let deviceId = "TEST-DEVICE-ID"
Amplitude.instance().setDeviceId(deviceId)
amplitude.setDeviceId(deviceId: deviceId)

clearUserProperties

Amplitude-Swift removes the clearUserProperties API, but you can use the unified identify API to remove user properties.

swift
Amplitude.instance().clearUserProperties()
let identify = Identify()
identify.clearAll()
amplitude.identify(identify: identify)

setUserProperties

Amplitude-Swift removes the setUserProperties API, but you can use the unified identify API to add user properties.

swift
Amplitude.instance().setUserProperties([
  "membership": "paid",
  "payment": "bank",
])
amplitude.identify(userProperties: [
  "membership": "paid",
  "payment": "bank"
])

identify

Make an identify call on amplitude without calling instance().

swift
let identify = AMPIdentify()
identify.set("membership", value: "paid")
Amplitude.instance().identify(identify)
let identify = Identify()
identify.set(property: "membership", value: "paid")
amplitude.identify(identify: identify)

Set group properties

groupIdentify

Make an identify call on amplitude without calling instance().

swift
let identify = AMPIdentify()
identify.set("membership", value: "paid")
Amplitude.instance().groupIdentify(
  withGroupType: "TEST-GROUP-TYPE",
  groupName: "TEST-GROUP-NAME",
  groupIdentify: identify
)

let identify = Identify()
identify.set(property: "membership", value: "paid")
amplitude.groupIdentify(
  groupType: "TEST-GROUP-TYPE",
  groupName: "TEST-GROUP-NAME",
  identify: identify
)

Track revenue

logRevenueV2

Track revenue using revenue() API on amplitude without calling instance().

swift
let revenue = AMPRevenue()
revenue.setProductIdentifier("productIdentifier")
revenue.setQuantity(3)
revenue.setPrice(NSNumber(value: 3.99))
Amplitude.instance().logRevenueV2(revenue)

let revenue = Revenue()
revenue.productId = "productIdentifier"
revenue.quantity = 3
revenue.price = 3.99
amplitude.revenue(revenue: revenue)

Patterns

Plugins

The configs amplitude.adSupportBlock or amplitude.useAdvertisingIdForDeviceId were available in Amplitude-iOS to allow you to use IDFV or IDFA as the deviceID. Although Amplitude-Swift doesn't support these configurations, you can add plugins to the new iOS SDK to enrich event payloads.

swift
import AdSupport
import AmplitudeSwift
import AppTrackingTransparency
import Foundation
import SwiftUI

/// Plugin to collect IDFA values.  Users will be prompted if authorization status is undetermined.
/// Upon completion of user entry a track event is issued showing the choice user made.
///
/// Don't forget to add "NSUserTrackingUsageDescription" with a description to your Info.plist.
class IDFACollectionPlugin: Plugin {
    let type = PluginType.enrichment
    weak var amplitude: Amplitude? = nil

    func execute(event: BaseEvent?) -> BaseEvent? {
        let status = ATTrackingManager.trackingAuthorizationStatus
        var idfa = fallbackValue
        if status == .authorized {
            idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
        }

        let workingEvent = event
        // The idfa on simulator is always 00000000-0000-0000-0000-000000000000
        event?.idfa = idfa
        // If you want to use idfa for the device_id
        event?.deviceId = idfa
        return workingEvent
    }
}

extension IDFACollectionPlugin {
    var fallbackValue: String? {
        // fallback to the IDFV value.
        // this is also sent in event.context.device.id,
        // feel free to use a value that is more useful to you.
        return UIDevice.current.identifierForVendor?.uuidString
    }
}

...
// To install your custom plugin, use 'add()' with your custom plugin as parameter.
amplitude.add(plugin: IDFACollectionPlugin())

Callback

Amplitude-Swift supports configuration-level and event-level callback functions that run on successful and failed uploads. The configuration-level callback runs on every successful and failed event upload. The event-level callback runs only for a specific event. Note that Amplitude-Swift stores event-level callbacks in cache, so the SDK loses these callbacks if the app crashes.

swift
let amplitude = Amplitude(
    configuration: Configuration(
        apiKey: "TEST-API-KEY",
        callback: { (event: BaseEvent, code: Int, message: String) -> Void in
            print("eventCallback: \(event), code: \(code), message: \(message)")
        },
    )
)

Event-level callbacks:

swift
let event = BaseEvent(
    callback: { (event: BaseEvent, code: Int, message: String) -> Void in
        print("eventCallback: \(event), code: \(code), message: \(message)")
    },
    eventType: "TEST-EVENT-TYPE")

amplitude.track(event: event)

or:

swift
let event2 = BaseEvent(eventType:"test")

amplitude.track(
    event: event2,
    callback: { (event: BaseEvent, code: Int, message: String) -> Void in
        print("eventCallback: \(event), code: \(code), message: \(message)")
})

Data migration

By default, Amplitude-Swift moves existing maintenance SDK data (events, user/device ID) to the latest SDK. To disable data migration, set migrateLegacyData to false in the Configuration.

If your macOS app isn't sandboxed, data from the legacy SDK doesn't migrate. For more information about sandboxing, and how to determine if your app is sandboxed, go to Apple's article Protecting user data with App Sandbox.

swift
amplitude = Amplitude(
    Configuration(
        ...
        migrateLegacyData: false,
    )
)

Was this helpful?