Skip to main content

Migrating from 0.x to 1.0

Version 1.0 is a major rewrite of the AppDNA SDK with breaking changes across all platforms. This guide walks you through every change you need to make to upgrade from 0.x.

Overview of Changes

Area0.x1.0
InitializationAppDNA.initialize()AppDNA.configure(apiKey:options:)
Method organizationFlat methods on AppDNANamespaced modules (e.g., AppDNA.onboarding)
DelegatesSingle global delegatePer-module delegates
Offline supportNetwork-dependentOffline-first with config bundles
API key formatappdna_ prefixadn_live_ / adn_test_ prefixes
IdentitysetUserId()identify(userId:traits:)
EventslogEvent()track(name:properties:)

1. Initialization

The initialize() method has been replaced with configure(), which now requires an explicit API key parameter and accepts an options object.
// 0.x
AppDNA.initialize(config: AppDNAConfig(
    projectId: "proj-123"
))

// 1.0
AppDNA.configure(
    apiKey: "adn_live_xxx",
    environment: .production,
    options: AppDNAOptions(logLevel: .debug)
)
The projectId is no longer needed. The API key encodes both the organization and app identifiers.

2. Module Namespaces

In 0.x, all methods lived directly on the AppDNA singleton. In 1.0, methods are organized into module namespaces:
0.x Method1.0 Equivalent
AppDNA.trackOnboardingStep()AppDNA.onboarding.trackStep()
AppDNA.presentOnboarding()AppDNA.onboarding.present()
AppDNA.showPaywall()AppDNA.paywall.present()
AppDNA.getProducts()AppDNA.billing.getProducts()
AppDNA.purchaseProduct()AppDNA.billing.purchase()
AppDNA.requestPushPermission()AppDNA.push.requestPermission()
AppDNA.getExperimentVariant()AppDNA.experiments.getVariant()
AppDNA.getRemoteConfig()AppDNA.remoteConfig.getString()
AppDNA.isFeatureEnabled()AppDNA.features.isEnabled()
AppDNA.showSurvey()AppDNA.surveys.present()
// 0.x
AppDNA.trackOnboardingStep("welcome", step: 2)
AppDNA.showPaywall("premium")
let variant = AppDNA.getExperimentVariant("test-1")

// 1.0
AppDNA.onboarding.trackStep("welcome", step: 2)
AppDNA.paywall.present("premium")
let variant = AppDNA.experiments.getVariant("test-1")

3. Delegates

In 0.x, there was a single AppDNADelegate protocol/interface that handled callbacks for all modules. In 1.0, each module has its own delegate:
0.x1.0
AppDNADelegateOnboardingDelegate
PaywallDelegate
BillingDelegate
PushDelegate
ExperimentDelegate
SurveyDelegate
// 0.x — single delegate
class AppController: AppDNADelegate {
    func onboardingCompleted(flowId: String) { ... }
    func paywallDismissed(paywallId: String) { ... }
    func pushReceived(notification: AppDNANotification) { ... }
}
AppDNA.delegate = AppController()

// 1.0 — per-module delegates
class OnboardingHandler: OnboardingDelegate {
    func onboardingDidComplete(flowId: String) { ... }
}

class PaywallHandler: PaywallDelegate {
    func paywallDidDismiss(paywallId: String, action: PaywallAction) { ... }
}

AppDNA.onboarding.delegate = OnboardingHandler()
AppDNA.paywall.delegate = PaywallHandler()

4. Config Bundles (New in 1.0)

Version 1.0 introduces config bundle embedding, a key part of the offline-first architecture. You can now embed a JSON config file in your app binary during CI/CD so the SDK has a complete configuration available on first launch without any network request. This is a new feature with no 0.x equivalent. See the Config Bundles in CI/CD guide for setup instructions.

5. API Key Format

API keys have changed format to clearly distinguish environments:
Environment0.x Format1.0 Format
Productionappdna_pk_xxxadn_live_xxx
Sandbox / Testappdna_sk_xxxadn_test_xxx
Old appdna_ prefixed keys are not compatible with 1.0 SDKs. Generate new API keys in Console > Settings > SDK > API Keys.

6. Identity

The setUserId() method has been replaced with identify(), which now accepts user traits for segmentation and targeting:
// 0.x
AppDNA.setUserId("user-123")

// 1.0
AppDNA.identify(
    userId: "user-123",
    traits: [
        "plan": "premium",
        "signup_date": "2025-01-15"
    ]
)
Traits are merged with previously set traits on each call. You only need to pass traits that have changed, not the full set every time.

7. Events

The logEvent() method has been replaced with track(), which accepts structured properties:
// 0.x
AppDNA.logEvent("purchase", metadata: ["price": "9.99"])

// 1.0
AppDNA.track(
    event: "purchase_completed",
    properties: ["price": 9.99, "currency": "USD"]
)
In 1.0, event properties support typed values (numbers, booleans, strings, arrays) rather than being limited to string-only metadata. This enables richer analytics and segmentation in the dashboard.

Platform-Specific Migration Notes

iOS

  • Minimum deployment target raised from iOS 13 to iOS 15.
  • Swift version requirement is now Swift 5.9+.
  • SPM package name changed from AppDNA to AppDNASDK. Update your import statements: import AppDNASDK.
  • Concurrency: Several async methods now use Swift concurrency (async/await) instead of completion handlers.

Android

  • Minimum SDK raised from API 21 to API 24 (Android 7.0).
  • Kotlin version requirement is now 1.9+.
  • Artifact coordinates changed from ai.appdna:core to ai.appdna:sdk.
  • Coroutines: Suspend functions are now used instead of callback-based APIs.

Flutter

  • Dart version requirement is now Dart 3.0+.
  • Flutter version requirement is now Flutter 3.10+.
  • Package name changed from appdna to appdna_sdk. Update your pubspec.yaml and import statements.

React Native

  • React Native version requirement is now 0.72+.
  • Package name changed from react-native-appdna to @appdna/react-native-sdk. Update your package.json and import statements.
  • New Architecture: Full support for the React Native New Architecture (TurboModules/Fabric).

Deprecation Timeline

DateMilestone
1.0 GA0.x SDKs enter maintenance mode. No new features.
1.0 GA + 3 months0.x SDKs receive critical bug fixes only.
1.0 GA + 6 months0.x SDKs reach end-of-life. No further updates, including security patches.
We strongly recommend migrating to 1.0 as soon as possible. After the 6-month deprecation window, 0.x SDKs will no longer receive security patches and may stop functioning if server-side API changes are made.