iOS SDK Migration Guide

SDK Comparison

Feature

iOS Swift SDK (current)

iOS SDK (maintenance)

Package

AmplitudeSwift

Amplitude

Configuration

Configuration is implemented by the configuration object. Configurations need to be passed into Amplitude Object during initialization

Supports specific setter methods.

Logger provider

ConsoleLogger() by default

AMPLITUDE_LOG configured through a macro

Storage provider

PersistentStorage() by default. File storage and iOS user’s defaults database. Fully customizable (not supported in Objective-C).

SQLite database

Customization

Plugins

MIddleware

Server endpoint

HTTP v2 API

HTTP v1 API

Batch API support

Yes, with configuration

Not supported

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

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

Terminiology

  • Amplitude-iOS: Maintenance iOS SDK
  • Amplitude-Swift: New iOS SDK

Dependencies

Add AmplitudeSwift dependency to Podfile.

1- pod 'Amplitude', '~> 8.14'
2+ pod 'AmplitudeSwift', '~> 1.0'

Enter https://github.com/amplitude/Amplitude-Swift into the search bar.

1- `https://github.com/amplitude/Amplitude-iOS`
2+ `https://github.com/amplitude/Amplitude-Swift`

Add amplitude/Amplitude-Swift to your Cartfile.

1- github "amplitude/Amplitude-iOS" ~> 8.14
2+ github "amplitude/Amplitude-Swift" ~> 1.0

Instrumentation changes

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

Initialize the SDK

Like all other calls, instance() has been removed. Configuration is handled differently between the maintenance iOS and new iOS SDK. The new iOS SDKs use the Configuration object to set the configuration.

-import Amplitude
+import AmplitudeSwift
3 
-Amplitude.instance().trackingSessionEvents = true
-Amplitude.instance().initializeApiKey("YOUR-API-KEY")
+let amplitude = Amplitude(configuration: Configuration(
+ apiKey: "YOUR-API-KEY",
+ defaultTracking: DefaultTrackingOptions(
+ sessions: true
+ )
+))

-#import "Amplitude.h"
+@import AmplitudeSwift;
3 
-[Amplitude instance].trackingSessionEvents = true;
-[[Amplitude instance] initializeApiKey:@"YOUR-API-KEY"];
+AMPConfiguration* configuration = [AMPConfiguration initWithApiKey:@"YOUR-API-KEY"];
+configuration.defaultTracking.sessions = true;
+Amplitude* amplitude = [Amplitude initWithConfiguration:configuration];

Configure the SDK

Amplitude-iOS Amplitude-Swift
amplitude.instanceWithName("YOUR-INSTANCE-NAME") config.instanceName
amplitude.useDynamicConfig NOT SUPPORTED.
amplitude.setServerUrl("YOUR-SERVER-URL") config.serverUrl
amplitude.setServerZone("AMPServerZone.EU or AMPServerZone.US") config.serverZone
amplitude.trackingOptions config.trackingOptions
amplitude.trackingSessionEvents config.defaultTracking.sessions
amplitude.minTimeBetweenSessionsMillis config.minTimeBetweenSessionsMillis
amplitude.eventUploadMaxBatchSize config.flushQueueSize
amplitude.eventUploadThreshold config.flushQueueSize
amplitude.eventUploadPeriodSeconds config.flushIntervalMillis
Set max retries count. NOT SUPPORTED. config.flushMaxRetries
amplitude.eventMaxCount NOT SUPPORTED.
amplitude.optOut config.optOut
amplitude.enableCoppaControl() or amplitude.disableCoppaControl() config.enableCoppaControl
Customize storage provider. NOT SUPPORTED. config.storageProvider
Set up log level. NOT SUPPORTED. config.logLevel
Customize logger provider. NOT SUPPORTED. config.loggerProvider
deviceId and userId don't have a minimum length. Minimum length is 5. config.minIdLength overwrites the minimum length ofdeviceId and userId.
Partner Id for partner integrations. NOT SUPPORTED. config.partnerId
The event callback. NOT SUPPORTED. See middleware. config.callback
amplitude.libraryName NOT SUPPORTED.
amplitude.libraryVersion NOT SUPPORTED.
amplitude.adSupportBlock NOT SUPPORTED. See Plugins.
amplitude.useAdvertisingIdForDeviceId NOT SUPPORTED. See Plugins.
amplitude.locationInfoBlock amplitude.locationInfoBlock
amplitude.deferCheckInForeground NOT SUPPORTED.
amplitude.setOffline(Yes) NOT SUPPORTED.
amplitude.setContentTypeHeader("YOUR-CONTENT-TYPE-HEADER") NOT SUPPORTED.
amplitude.setPlan(plan) config.plan
plan.setBranch("YOUR-BRANCH") config.plan.branch
plan.setSource("YOUR-SOURCE") config.plan.source
plan.setVersion("YOUR-VERSION") config.plan.version
plan.setVersionId("YOUR-VERSION-ID") config.plan.versionId
amplitude.setTrackingOptions(options) config.trackingOptions
amplitude.setSessionId(timestamp) NOT SUPPORTED.

Track events

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

logEvent

The logEvent() API maps to track().

1let eventType = "Button Clicked"
2let eventProperties: [String: Any] = ["key": "value"]
3 
-Amplitude.instance().logEvent(
- eventType,
- withEventProperties: eventProperties
-)
+let event = BaseEvent(
+ eventType: eventType,
+ eventProperties: eventProperties
+)
+amplitude.track(event)

1NSString* eventType = @"Button Clicked";
2NSDictionary* eventProperties = @{@"key": @"value"};
3 
-[[Amplitude instance] logEvent:eventType withEventProperties:eventProperties];
+AMPBaseEvent* event = [AMPBaseEvent initWithEventType:eventType
+ eventProperties:eventProperties];
+[amplitude track:event];

logEvent withTimestamp

The logEvent() API maps to track().

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

1NSString* eventType = @"Button Clicked";
2NSNumber* timestamp = [NSNumber numberWithLongLong:[[NSDate date] timeIntervalSince1970] * 1000];
3 
-[[Amplitude instance] logEvent:eventType withTimestamp:timestamp];
+AMPBaseEvent* event = [AMPBaseEvent initWithEventType:eventType];
+event.timestamp = [timestamp longLongValue];
+[amplitude track:event];

logEvent withGroup

The logEvent() API maps to track().

1let eventType = "Button Clicked"
2let eventProperties: [String: Any] = ["key": "value"]
3let groups: [String: Any] = ["orgId": 10]
4 
-Amplitude.instance().logEvent(
- eventType,
- withEventProperties: eventProperties,
- withGroups: groups
-)
+let event = BaseEvent(
+ eventType: eventType,
+ eventProperties: eventProperties,
+ groups: groups
+)
+amplitude.track(event)

1NSString* eventType = @"Button Clicked";
2NSDictionary* eventProperties = @{@"key": @"value"};
3 
-NSDictionary* groups = @{@"orgId": @"10"};
-[[Amplitude instance] logEvent:eventType
- withEventProperties:eventProperties
- withGroups:groups];
+AMPBaseEvent* event = [AMPBaseEvent initWithEventType:eventType
+ eventProperties:eventProperties];
+[event.groups set:@"orgId" value:@"10"];
+[amplitude track:event];

uploadEvents

The uploadEvents() API maps to flush().

-Amplitude.instance().uploadEvents()
+amplitude.flush()

-[[Amplitude instance] uploadEvents];
+[amplitude flush];

Set user properties

The APIs for setting user properties are the same, except for the removal of instance(). Here are code snippets to migrate APIs for user properties.

setUserId

ID length limit

The maintenance SDK uses an old SDK endpoint (api2.amplitude.com) which 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 to be at least 5 characters by default. When you migrate to the latest SDK, set config.minIdLength to a smaller value if you allowed identifiers with fewer than 5 characters.

Setting a user ID can be invoked on amplitude without calling getInstance().

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

1NSString* userId = @"TEST-USER-ID";
-[[Amplitude instance] setUserId:userId];
+[amplitude setUserId:userId];

setDeviceId

ID length limit

The maintenance SDK uses an old SDK endpoint (api2.amplitude.com) which 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 to be at least 5 characters by default. When you migrate to the latest SDK, set config.minIdLength to a smaller value if you allowed identifiers with fewer than 5 characters.

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

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

1NSString* deviceId = @"TEST-DEVICE-ID";
-[[Amplitude instance] setDeviceId:deviceId];
+[amplitude setDeviceId:deviceId];

clearUserProperties

The clearUserProperties API has been removed, but you can now use the unified identify API to remove user properties.

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

-[[Amplitude instance] clearUserProperties];
+AMPIdentify* identify = [AMPIdentify new];
+[identify clearAll];
+[amplitude identify:identify];

setUserProperties

The setUserProperties API has been removed, but you can now use the unified identify API to add user properties.

1Amplitude.instance().setUserProperties([ //[tl! --:3]
2 "membership": "paid",
3 "payment": "bank",
4])
5amplitude.identify(userProperties: [ //[tl! ++:3]
6 "membership": "paid",
7 "payment": "bank"
8])

1[[Amplitude instance] setUserProperties:@{ //[tl! --:3]
2 @"membership": @"paid",
3 @"payment": @"bank"
4}];
5AMPIdentify* identify = [AMPIdentify new]; //[tl! ++:3]
6[identify set:@"membership" value:@"paid"];
7[identify set:@"payment" value:@"bank"];
8[amplitude identify:identify];

identify

You can now make an identify call on amplitude without calling instance().

-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)

1AMPIdentify* identify = [AMPIdentify new];
2[identify set:@"membership" value:@"paid"];
3 
-[[Amplitude instance] identify:identify];
+[amplitude identify:identify];

Set group properties

groupIdentify

You can now make an identify call on amplitude without calling instance().

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

1AMPIdentify* identify = [AMPIdentify new];
2[identify set:@"membership" value:@"paid"];
3 
-[[Amplitude instance] groupIdentifyWithGroupType:@"TEST-GROUP-TYPE"
- groupName:@"TEST-GROUP-NAME"
- groupIdentify:identify];
+[amplitude groupIdentify:@"TEST-GROUP-TYPE"
+ groupName:@"TEST-GROUP-NAME"
+ identify:identify];

Track revenue

logRevenueV2

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

-let revenue = AMPRevenue()
-revenue.setProductIdentifier("productIdentifier")
-revenue.setQuantity(3)
-revenue.setPrice(NSNumber(value: 3.99))
-Amplitude.instance().logRevenueV2(revenue)
6 
+let revenue = Revenue()
+revenue.productId = "productIdentifier"
+revenue.quantity = 3
+revenue.price = 3.99
+amplitude.revenue(revenue: revenue)

1AMPRevenue* revenue = [AMPRevenue new];
2 
-[revenue setProductIdentifier:@"productidentifier"];
-[revenue setQuantity:3];
-[revenue setPrice:@3.99];
-[[Amplitude instance] logRevenueV2:revenue];
+revenue.productId = @"productidentifier";
+revenue.quantity = 3;
+revenue.price = 3.99;
+[amplitude 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.

1import AdSupport
2import AmplitudeSwift
3import AppTrackingTransparency
4import Foundation
5import SwiftUI
6 
7/// Plugin to collect IDFA values. Users will be prompted if authorization status is undetermined.
8/// Upon completion of user entry a track event is issued showing the choice user made.
9///
10/// Don't forget to add "NSUserTrackingUsageDescription" with a description to your Info.plist.
11class IDFACollectionPlugin: Plugin {
12 let type = PluginType.enrichment
13 weak var amplitude: Amplitude? = nil
14 
15 func execute(event: BaseEvent?) -> BaseEvent? {
16 let status = ATTrackingManager.trackingAuthorizationStatus
17 var idfa = fallbackValue
18 if status == .authorized {
19 idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
20 }
21 
22 let workingEvent = event
23 // The idfa on simulator is always 00000000-0000-0000-0000-000000000000
24 event?.idfa = idfa
25 // If you want to use idfa for the device_id
26 event?.deviceId = idfa
27 return workingEvent
28 }
29}
30 
31extension IDFACollectionPlugin {
32 var fallbackValue: String? {
33 // fallback to the IDFV value.
34 // this is also sent in event.context.device.id,
35 // feel free to use a value that is more useful to you.
36 return UIDevice.current.identifierForVendor?.uuidString
37 }
38}
39 
40...
41// To install your custom plugin, use 'add()' with your custom plugin as parameter.
42amplitude.add(plugin: IDFACollectionPlugin())

1@import AmplitudeSwift;
2#import <AppTrackingTransparency/AppTrackingTransparency.h>
3#import <AdSupport/ASIdentifierManager.h>
4 
5[amplitude add:[AMPPlugin initWithType:AMPPluginTypeEnrichment execute:^AMPBaseEvent* _Nullable(AMPBaseEvent* _Nonnull event) {
6 ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
7 
8 // fallback to the IDFV value.
9 // this is also sent in event.context.device.id,
10 // feel free to use a value that is more useful to you.
11 NSUUID* idfaUUID = [UIDevice currentDevice].identifierForVendor;
12 
13 if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
14 idfaUUID = [ASIdentifierManager sharedManager].advertisingIdentifier;
15 }
16 
17 NSString* idfa = (idfaUUID != nil) ? idfaUUID.UUIDString : nil;
18 
19 // The idfa on simulator is always 00000000-0000-0000-0000-000000000000
20 event.idfa = idfa;
21 // If you want to use idfa for the device_id
22 event.deviceId = idfa;
23 return event;
24}]];

Callback

Amplitude-Swift supports configuration-level and event-level callback functions which are called for success and error upload. Configuration-level callback applies for every success and error event upload. Event-level callback is specific for one Event. Notice that the event-level callbacks are stored in cache, those callbacks are lost if the app crashes.

1let amplitude = Amplitude(
2 configuration: Configuration(
3 apiKey: "TEST-API-KEY",
4 callback: { (event: BaseEvent, code: Int, message: String) -> Void in
5 print("eventCallback: \(event), code: \(code), message: \(message)")
6 },
7 )
8)

1AMPConfiguration* configuration = [AMPConfiguration initWithApiKey:@"YOUR-API-KEY"];
2configuration.callback = ^(AMPBaseEvent* _Nonnull event, NSInteger code, NSString* _Nonnull message) {
3 NSLog(@"eventCallback: %@, code: %@, message: %@", event.eventType, @(code), message);
4};
5Amplitude* amplitude = [Amplitude initWithConfiguration:configuration];

Event-level callbacks:

1let event = BaseEvent(
2 callback: { (event: BaseEvent, code: Int, message: String) -> Void in
3 print("eventCallback: \(event), code: \(code), message: \(message)")
4 },
5 eventType: "TEST-EVENT-TYPE")
6 
7amplitude.track(event: event)

or:

1let event2 = BaseEvent(eventType:"test")
2 
3amplitude.track(
4 event: event2,
5 callback: { (event: BaseEvent, code: Int, message: String) -> Void in
6 print("eventCallback: \(event), code: \(code), message: \(message)")
7})

1AMPBaseEvent* event = [AMPBaseEvent initWithEventType:@"TEST-EVENT-TYPE"];
2event.callback = ^(AMPBaseEvent* _Nonnull event, NSInteger code, NSString* _Nonnull message) {
3 NSLog(@"eventCallback: %@, code: %@, message: %@", event.eventType, @(code), message);
4};
5 
6[amplitude track:event];

or:

1AMPBaseEvent* event2 = [AMPBaseEvent initWithEventType:@"test"];
2 
3[amplitude track:event2 callback:^(AMPBaseEvent* _Nonnull event, NSInteger code, NSString* _Nonnull message) {
4 NSLog(@"eventCallback: %@, code: %@, message: %@", event.eventType, @(code), message);
5}];

Data migration

Existing maintenance SDK data (events, user/device ID) are moved to the latest SDK by default. It can be disabled by setting migrateLegacyData to false in the Configuration.

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

1amplitude = Amplitude(
2 Configuration(
3 ...
4 migrateLegacyData: false,
5 )
6)

1AMPConfiguration* configuration = [AMPConfiguration initWithApiKey:@"YOUR-API-KEY"];
2configuration.migrateLegacyData = false;
3Amplitude* amplitude = [Amplitude initWithConfiguration:configuration];

Was this page helpful?

Thanks for your feedback!

May 14th, 2024

Need help? Contact Support

Visit Amplitude.com

Have a look at the Amplitude Blog

Learn more at Amplitude Academy

© 2024 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.