App Privacy & Data Collection
Apple Privacy Manifest mapping and the data the SDK collects
The Convert iOS SDK collects no personally identifiable information on its own. The only identifier it generates locally is an app-scoped UUID used for experiment bucketing, stored in the Keychain (system of record) with a UserDefaults mirror for fast reads. Events sent to Convert contain: the visitor id (the UUID), any segments you set, and experiment/goal identifiers. No device identifiers, no advertising identifier (no IDFA, no IDFV), no location data, no contacts, no user-profile data.
This page maps the SDK's data behavior onto Apple's App Privacy questionnaire (App Store Connect) and explains every entry in the shipped PrivacyInfo.xcprivacy Apple Privacy Manifest.
You remain responsible for declaring any user-derived data you pass into the SDK.
Apple Privacy Manifest (PrivacyInfo.xcprivacy)
PrivacyInfo.xcprivacy)The SDK ships Sources/ConvertSwiftSDK/Resources/PrivacyInfo.xcprivacy as a .process-type resource that Xcode bundles into your app's manifest. Apple requires privacy manifests for SDKs designated as tracking-capable; Convert is designated as requiring one because A/B testing SDKs fall under that category.
Tracking declaration
NSPrivacyTracking = false
NSPrivacyTrackingDomains = (empty)
The SDK does no cross-app or cross-site tracking. It reads neither the IDFA nor the IDFV, shows no App Tracking Transparency (ATT) prompt, and your app does not need to call ATTrackingManager on Convert's behalf.
Collected data types
The manifest declares exactly two collected data types:
Data type (NSPrivacyCollectedDataType) | What it is in Convert | Linked to user | Used for tracking | Purposes |
|---|---|---|---|---|
NSPrivacyCollectedDataTypeDeviceID | The generated visitor UUID (not IDFA/IDFV) | false | false | App Functionality, Analytics |
NSPrivacyCollectedDataTypeProductInteraction | Experiment exposures and goal conversions | false | false | App Functionality, Analytics |
Both are declared not linked to the user's identity and not used for tracking. The two purposes mean the same data does two jobs: App Functionality (deciding which variation to serve) and Analytics (the conversion reports you read in Convert).
Required-reason API
The manifest declares one required-reason API:
API (NSPrivacyAccessedAPIType) | Reason code | Why |
|---|---|---|
NSPrivacyAccessedAPICategoryUserDefaults | CA92.1 | The SDK reads and writes UserDefaults solely to mirror the visitor identifier for fast reads — values only accessible to the app itself. |
App Store App Privacy questionnaire mapping
Paste the following into your App Store App Privacy questionnaire for the portion contributed by this SDK. There are no placeholders to fill in.
Data used for tracking: None. The Convert SDK performs no cross-app or cross-site tracking. It reads no advertising identifier (no IDFA, no IDFV) and shows no App Tracking Transparency prompt.
Data collected — Device ID. The Convert SDK assigns each visitor a randomly generated UUID to keep A/B-test assignments consistent across launches. It is not an advertising identifier and is not linked to the user's identity. Used for App Functionality and Analytics. Not used to track the user.
Data collected — Product Interaction. The Convert SDK records which experiment variation a visitor was shown and which in-app goals they completed, so the experiment can run and its results can be reported. This data is not linked to the user's identity. Used for App Functionality and Analytics. Not used to track the user.
In Apple's questionnaire these map to the Identifiers → Device ID and Usage Data → Product Interaction categories, each with "Used to Track You" = No and "Linked to the User" = No.
Per-data-type declarations (SDK-generated data only)
| Data type | Collected | Shared | Purposes |
|---|---|---|---|
| Device or other IDs | Yes (the visitor UUID) | Yes (sent to Convert in event payloads) | App Functionality, Analytics |
| Product Interaction (bucketing + conversion events) | Yes | Yes (sent to Convert) | App Functionality, Analytics |
| Personal info | No | No | None |
| Location | No | No | Audience location rules use inputs you provide via setDefaultSegments / setCustomSegments; the SDK collects no location itself |
| Financial info | No | No | Transaction values you attach via GoalData (amount, transactionId) are aggregate analytics inputs, not per-user financial records |
| Contacts / Messages / Photos / Audio / Files / Calendar / Health / Web browsing | No | No | None |
Data you pass in
If your app passes user-derived attributes (for example plan, country, accountAgeDays) into createContext(attributes:), setDefaultSegments(_:), or setCustomSegments(_:), those values flow through to Convert. Declare them separately on the App Privacy form according to your own privacy posture and the meaning of the data you send.
The visitor ID
The default visitor id is a version-4 (random) UUID generated on-device the first time a context is created without an explicit visitorId. It is stored in the Keychain (system of record) with a UserDefaults mirror for fast reads.
- It is a 122-bit random value with no correlation to the user's real identity.
- It is not the IDFA or IDFV and carries no advertising linkage.
- It is discarded from
UserDefaultson app uninstall; the Keychain copy may survive depending on your app's Keychain sharing settings. - If you supply your own explicit visitor id via
sdk.createContext(visitorId: "your-id"), you control what that id reveals — declare accordingly on the App Privacy form.
No consent management — you own the decision
The SDK ships no consent-management UI. It does not store a consent flag, present a consent dialog, or gate itself on one. Consent is your decision to make, and you enforce it with the controls the SDK provides:
- Don't initialize. If a user has not consented, simply do not construct
ConvertSwiftSDK. No identifier is generated, no bucketing runs, no event is sent. - Disable delivery at init time (static). Set
ConvertConfiguration(sdkKey:, networkTracking: false). Bucketing still resolves so your UI can decide, but no exposure or conversion event is ever sent. - Disable delivery for a single experience (per-call). Pass
enableTracking: falsetocontext.runExperience(_:enableTracking:). Note this per-call flag governs the experience path only; the feature path (runFeature/runFeatures) takes noenableTrackingparameter (Android parity). - Disable delivery at runtime (mid-session). Call
await sdk.setTrackingEnabled(false)at any point after initialization. Re-enable withawait sdk.setTrackingEnabled(true)(suppressed events are not replayed). This is the supported consent-withdrawal path for GDPR mid-session opt-out.
Related pages
- Tracking Control — the four tracking-control mechanisms in depth
- Visitor Context & Properties — the shared visitor-identity concept doc
- Segments — what segments are and how they are reported