Skip to content

Versioning & compatibility

What "still in early development" means for you in practice, and how to avoid painting yourself into a corner.

Platform support

Two different things are often confused, so let's be explicit.

Canonical page

This table is the canonical statement of platform support. Other pages link here rather than restating it.

iOS Android
Upload, channels, releases, testers
Install links and tester portal
How a tester installs Over-the-air (itms-services manifest) Direct download and install of the .apk
In-app updates SDK (Swift package)
/sdk/v1 HTTP endpoints

AppGantry distributes iOS and Android. Android is a fully supported distribution platform, not a roadmap item.

The two install flows are genuinely different, and it's worth not blurring them: iOS installs over the air from an itms-services manifest AppGantry generates, while Android is a direct install/download — the tester downloads the .apk and installs it. Calling the Android flow "OTA" invites the wrong expectations.

The in-app updates SDK documented in this section is iOS-specific. It's a Swift package built for the iOS in-app update flow. There is no Android library today. AppGantry does not offer macOS app distribution, so don't read the package's build requirements as a distribution claim.

If you want in-app update checks on Android — or in Kotlin, Flutter, React Native, or Unity — call the /sdk/v1 endpoints yourself. They are the same enroll, latest-update, download, and install-reporting operations the Swift package uses, they are ordinary HTTP, and they are documented operation by operation in SDK HTTP API. The generated schema for all seven is in the interactive API reference.

The SDK's Platform enum models android, tvOS, watchOS, visionOS, and wearOS as values so the protocol can express them; a value in an enum is not a shipped client library.

SDK stability

The SDK is on the main branch of the iOS-SDK repository. There are no tagged releases yet.

What that means:

  • Pin to a commit, not to a branch. Swift Package Manager's branch: requirement re-resolves to whatever main points at, which means an unrelated swift package update can change your app's behaviour. Use revision: with an explicit commit SHA and move it deliberately. Commit your Package.resolved as a second safeguard. See Installation.
  • Expect source-breaking changes. Method signatures and types may change until there is a tagged release.
  • Read the diff when you bump. Until releases are tagged, the commit history is the changelog.

Once tagged releases exist, semantic versioning will make this straightforward. Until then, treat the SDK as a dependency you upgrade on purpose.

Backend compatibility

The /sdk/v1 surface is versioned in its path. Changes within v1 are additive: new fields may appear in responses, and your client should ignore unknown ones rather than failing.

This matters more for the SDK than for anything else you integrate, because shipped apps cannot be patched from the server. A version of your app on a user's phone will keep calling the endpoints it was built against for as long as that user keeps it. Design accordingly:

  • Ignore unknown response fields.
  • Handle every error case, including ones you don't expect yet. See Tokens and errors.
  • Fail soft. If the update check fails, the app should carry on. An app that refuses to start because it couldn't reach the update service is worse than an app that's a version behind.

App versions and update ordering

The SDK asks "is there a newer build for this install?" and AppGantry answers based on the channel's current release.

  • Version comparison follows your build metadata. Give builds monotonically increasing build numbers. Reusing or reversing them makes "newer" ambiguous, and ambiguity in an update prompt is user-visible.
  • Mandatory releases are flagged in the response so you can present a non-dismissible prompt. Whether you honour that is your app's choice; the SDK just reports it. See Channels & releases.
  • Rollbacks can move a channel backwards. If you roll back, an install that already has the newer build will not be told to downgrade. Plan a forward fix rather than expecting rollback to retrieve builds already installed.

Rotating the app secret

The app secret is embedded in the shipped binary, so rotation is a release, not a settings change.

There is no rotate action: you revoke an SDK app and create a new one. Revoking is immediate, and it affects every app version carrying the old secret.

The safe sequence:

  1. Create a new SDK app on the channel. Copy the secret — it's shown once.
  2. Ship an app build using the new key and secret.
  3. Wait for adoption. Watch channel analytics.
  4. Revoke the old SDK app.

The unsafe sequence is revoking first: every install still on the old build immediately loses its ability to renew, and cannot recover without a manual reinstall.

If a secret is compromised, revoke immediately and accept the disruption. The blast radius is deliberately narrow — one channel, enrollment only — but a leaked secret lets a stranger enroll and download your builds.

Token lifecycle at a glance

Credential Lifetime Renewal
App key Until the SDK app is revoked n/a — public identifier
App secret Until the SDK app is revoked Replace the SDK app, ship a build
Per-install update token 30 days The SDK re-enrolls using the app secret

An install that hasn't opened your app in more than 30 days will re-enroll on the next check. That's handled for you.

Deprecation

When a breaking change to /sdk/v1 becomes necessary, it will land as a new version path rather than a change to v1, and the old version will keep working for a transition period. Shipped apps can't be recalled, so we don't break them.

See also