> ## Documentation Index
> Fetch the complete documentation index at: https://docs.permutive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Common Issues

> Solutions to common Permutive iOS SDK problems

This guide covers common issues and their solutions when integrating the Permutive iOS SDK.

<CardGroup cols={3}>
  <Card title="Installation" href="#installation-issues" icon="download" />

  <Card title="Initialization" href="#initialization-issues" icon="gear" />

  <Card title="Tracking" href="#tracking-issues" icon="bolt" />
</CardGroup>

## Installation Issues

<AccordionGroup>
  <Accordion title="CocoaPods: Pod not found">
    **Error:** `Unable to find a specification for 'Permutive_iOS'`

    **Solutions:**

    1. Update your CocoaPods repo:
       ```bash theme={"dark"}
       pod repo update
       ```
    2. Ensure CocoaPods is version 1.9.1 or later:
       ```bash theme={"dark"}
       pod --version
       ```
    3. Clear the cache:
       ```bash theme={"dark"}
       pod cache clean --all
       pod install
       ```
  </Accordion>

  <Accordion title="SPM: Package resolution failed">
    **Error:** Xcode cannot resolve the package.

    **Solutions:**

    1. Check your network connection
    2. Reset package caches: **File → Packages → Reset Package Caches**
    3. Verify the URL is correct: `https://github.com/permutive-engineering/permutive-ios-spm`
    4. Try removing and re-adding the package
  </Accordion>

  <Accordion title="Module not found after installation">
    **Error:** `No such module 'Permutive_iOS'`

    **Solutions:**

    1. Clean build folder: **Product → Clean Build Folder** (⇧⌘K)
    2. For CocoaPods: Ensure you opened the `.xcworkspace` file, not `.xcodeproj`
    3. Restart Xcode
    4. For SPM: Reset package caches
  </Accordion>

  <Accordion title="Bitcode errors">
    **Error:** Bitcode-related build errors.

    **Solution:** Disable Bitcode in your target's Build Settings:

    * Set **Enable Bitcode** to **No**

    Bitcode is no longer required for App Store submission.
  </Accordion>

  <Accordion title="Duplicate symbols">
    **Error:** Duplicate symbol errors during linking.

    **Solutions:**

    1. Ensure you're not mixing CocoaPods and SPM for Permutive
    2. Check for conflicting library versions
    3. Clean derived data: `rm -rf ~/Library/Developer/Xcode/DerivedData`
  </Accordion>
</AccordionGroup>

## Initialization Issues

<AccordionGroup>
  <Accordion title="Options returns nil">
    **Problem:** `Options(apiKey:organisationId:workspaceId:)` returns nil.

    **Causes:**

    * Empty or whitespace-only credentials
    * Invalid credential format

    **Solution:** Verify your credentials:

    ```swift theme={"dark"}
    let apiKey = "<your-api-key>".trimmingCharacters(in: .whitespacesAndNewlines)
    let orgId = "<your-org-id>".trimmingCharacters(in: .whitespacesAndNewlines)
    let workspaceId = "<your-workspace-id>".trimmingCharacters(in: .whitespacesAndNewlines)

    guard !apiKey.isEmpty, !orgId.isEmpty, !workspaceId.isEmpty else {
        print("Credentials are empty")
        return
    }

    guard let options = Options(apiKey: apiKey, organisationId: orgId, workspaceId: workspaceId) else {
        print("Invalid credential format")
        return
    }
    ```
  </Accordion>

  <Accordion title="Initialization fails silently">
    **Problem:** No error, but SDK doesn't seem to work.

    **Solution:** Enable debug logging and check for errors:

    ```swift theme={"dark"}
    options.logModes = LogMode.all

    Permutive.shared.start(with: options) { error in
        if let error = error {
            print("Initialization failed: \(error)")
        } else {
            print("SDK initialized successfully")
        }
    }
    ```
  </Accordion>

  <Accordion title="Network error during initialization">
    **Problem:** Initialization fails with network error.

    **Solutions:**

    1. Check device network connectivity
    2. Verify no firewall is blocking Permutive domains
    3. Check if running on simulator with network issues
    4. Retry initialization:
       ```swift theme={"dark"}
       Permutive.shared.start(with: options) { error in
           if error != nil {
               // Retry after delay
               DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                   Permutive.shared.start(with: options, completion: nil)
               }
           }
       }
       ```
  </Accordion>

  <Accordion title="SDK not ready when tracking">
    **Problem:** Events tracked before initialization completes are lost.

    **Solution:** Wait for the completion callback:

    ```swift theme={"dark"}
    Permutive.shared.start(with: options) { error in
        guard error == nil else { return }
        // Now safe to track
        self.startTracking()
    }
    ```
  </Accordion>
</AccordionGroup>

## Tracking Issues

<AccordionGroup>
  <Accordion title="Events rejected with schema error">
    **Error:**

    ```
    Permutive: [error] Schema validation failed with reason(s): [#: extraneous key [invalid_key] is not permitted]
    ```

    **Causes:**

    * Property names don't match schema
    * Property types don't match schema
    * Extra properties not in schema

    **Solutions:**

    1. Check your Permutive dashboard for the correct schema
    2. Verify property names exactly (case-sensitive)
    3. Remove any extra properties
    4. Verify property types match (string, int, bool, etc.)
  </Accordion>

  <Accordion title="EventProperties init throws">
    **Error:** `EventProperties` constructor throws an exception.

    **Causes:**

    * Unsupported value types
    * Invalid nested objects

    **Solutions:**
    Ensure all values are supported types:

    ```swift theme={"dark"}
    // Supported types:
    // String, Int, Float, Double, Bool, Date, EventProperties, and arrays of these

    // ❌ Wrong - Custom object
    let props = try EventProperties(["user": myUserObject])

    // ✅ Correct - Primitive types
    let props = try EventProperties([
        "user_id": user.id,           // String
        "user_name": user.name,       // String
        "age": user.age               // Int
    ])
    ```
  </Accordion>

  <Accordion title="Pageview event not firing">
    **Problem:** No Pageview event in logs.

    **Solutions:**

    1. Ensure `resume()` is called:
       ```swift theme={"dark"}
       override func viewDidAppear(_ animated: Bool) {
           super.viewDidAppear(animated)
           try? pageTracker?.resume()  // Must call this
       }
       ```
    2. Check PageTracker was created successfully
    3. Verify SDK is initialized before creating PageTracker
    4. Enable debug logging
  </Accordion>

  <Accordion title="PageTracker stops unexpectedly">
    **Problem:** PageTracker stops when navigating or creating new trackers.

    **Cause:** Only one PageTracker/MediaTracker can be active at a time.

    **Solution:** This is expected behavior. Creating a new tracker stops any existing one. Design your flow accordingly.
  </Accordion>

  <Accordion title="No log output">
    **Problem:** Console is silent, no Permutive logs appear.

    **Solutions:**

    1. Confirm `logModes` is set before `start()`:
       ```swift theme={"dark"}
       options.logModes = LogMode.all  // Must set before start()
       Permutive.shared.start(with: options) { ... }
       ```
    2. Check Xcode console filter isn't hiding messages
    3. Verify SDK is actually being initialized
  </Accordion>
</AccordionGroup>

## Cohort and Activation Issues

<AccordionGroup>
  <Accordion title="Empty cohorts">
    **Problem:** `Permutive.shared.cohorts` returns an empty set.

    **Causes:**

    * SDK just initialized (cohorts not yet synced)
    * No events tracked yet
    * User doesn't qualify for any cohorts

    **Solutions:**

    1. Wait a few seconds after initialization
    2. Track some events to generate data
    3. Use TriggerProvider for reactive updates
    4. Check your dashboard for cohort definitions
  </Accordion>

  <Accordion title="Activations different from cohorts">
    **Problem:** User is in a cohort but it doesn't appear in activations.

    **Cause:** Not all cohorts are activated for all platforms.

    **Solution:** Check your Permutive dashboard configuration. Activations must be explicitly configured for each platform (GAM, Xandr, etc.).
  </Accordion>

  <Accordion title="Contextual cohorts not appearing">
    **Problem:** `dfp_contextual` or `appnexus_adserver_contextual` is empty.

    **Solutions:**

    1. Verify contextual features are enabled (contact your CSM)
    2. Update to SDK 2.0.0+
    3. Ensure PageTracker has a valid, publicly accessible URL
    4. Allow time for content analysis (1-2 seconds)
    5. Check debug logs for classification errors
  </Accordion>
</AccordionGroup>

## Identity Issues

<AccordionGroup>
  <Accordion title="setIdentityForIDFA fails">
    **Error:** `setIdentityForIDFA` throws an error.

    **Cause:** IDFA is all zeros (tracking denied/restricted).

    **Solution:**

    ```swift theme={"dark"}
    if #available(iOS 14, *) {
        let status = ATTrackingManager.trackingAuthorizationStatus
        guard status == .authorized else {
            // Use alternative identity
            return
        }
    }

    let idfa = ASIdentifierManager.shared().advertisingIdentifier
    guard idfa != UUID(uuidString: "00000000-0000-0000-0000-000000000000") else {
        // IDFA not available
        return
    }

    try Permutive.shared.setIdentityForIDFA(idfa)
    ```
  </Accordion>

  <Accordion title="Reserved tag error">
    **Problem:** Alias with certain tags is ignored.

    **Cause:** Reserved tags: `appnexus`, `amp`, `gigya`, `sailthru`, `aaid`

    **Solution:** Use custom tag names:

    ```swift theme={"dark"}
    // ❌ Wrong
    Alias(tag: "appnexus", identity: id)  // Reserved, will be ignored

    // ✅ Correct
    Alias(tag: "my_appnexus_id", identity: id)
    ```
  </Accordion>

  <Accordion title="Identity not merging across devices">
    **Problem:** Same user appears as different users on different devices.

    **Solution:** Use consistent identifiers that work across devices:

    ```swift theme={"dark"}
    // Best: Hashed email (works across all devices)
    Alias(tag: "email_sha256", identity: hashedEmail, priority: 0)

    // Good: Your internal user ID
    Alias(tag: "internal_id", identity: userId, priority: 1)
    ```
  </Accordion>
</AccordionGroup>

## Ad Integration Issues

<AccordionGroup>
  <Accordion title="No targeting data in ad request">
    **Problem:** `googleCustomTargeting` returns empty or minimal data.

    **Solutions:**

    1. Verify SDK is initialized before calling
    2. Check that cohorts exist for the user
    3. Wait for cohort data to sync after initialization
    4. Enable debug logging to see activations
  </Accordion>

  <Accordion title="View ID missing from targeting">
    **Problem:** `prmtvvid` key not in targeting dictionary.

    **Solution:** Pass the active PageTracker:

    ```swift theme={"dark"}
    // ❌ Wrong - no view ID
    Permutive.shared.googleCustomTargeting(adTargetable: nil)

    // ✅ Correct - includes view ID
    Permutive.shared.googleCustomTargeting(adTargetable: pageTracker)
    ```
  </Accordion>
</AccordionGroup>

## TriggerProvider Issues

<AccordionGroup>
  <Accordion title="Trigger callbacks not firing">
    **Problem:** No callbacks when cohort membership changes.

    **Solutions:**

    1. Store a strong reference to TriggerAction:
       ```swift theme={"dark"}
       class MyController {
           // Store as property, not local variable
           private var trigger: TriggerAction?

           func setup() {
               trigger = Permutive.shared.triggerProvider?.action(...)
           }
       }
       ```
    2. Verify cohort IDs match your dashboard exactly
    3. Enable debug logging to see cohort updates
  </Accordion>

  <Accordion title="Trigger stops working">
    **Problem:** Trigger worked initially but stopped.

    **Cause:** TriggerAction reference was released.

    **Solution:** Keep TriggerAction as an instance property for the lifetime you need it.
  </Accordion>
</AccordionGroup>

## Debug Logging

Enable comprehensive logging for troubleshooting:

```swift theme={"dark"}
guard let options = Options(
    apiKey: "<your-api-key>",
    organisationId: "<your-org-id>",
    workspaceId: "<your-workspace-id>"
) else { return }

// Enable all logging
options.logModes = LogMode.all

Permutive.shared.start(with: options) { error in
    // Check console for detailed logs
}
```

### Log Messages to Look For

| Message                    | Meaning                   |
| -------------------------- | ------------------------- |
| `SDK ready`                | Initialization successful |
| `Accepted: X / X`          | Events sent successfully  |
| `event rejection`          | Schema validation failed  |
| `Schema validation failed` | Property mismatch         |

<Warning>
  Always disable debug logging in production builds to avoid performance overhead.
</Warning>

```swift theme={"dark"}
#if DEBUG
options.logModes = LogMode.all
#else
options.logModes = LogMode.none
#endif
```

## Getting Help

If you can't resolve an issue:

1. **Enable debug logging** and capture relevant logs
2. **Check SDK version** - ensure you're on the latest
3. **Contact support:**
   * [Support](mailto:support@permutive.com)

Include in your support request:

* SDK version
* iOS/tvOS version
* Xcode version
* Relevant logs
* Steps to reproduce

## Related Documentation

<CardGroup cols={2}>
  <Card title="Installation" icon="download" href="/sdks/mobile/ios/getting-started/installation">
    Setup troubleshooting
  </Card>

  <Card title="Initialization" icon="gear" href="/sdks/mobile/ios/getting-started/initialization">
    Configuration options
  </Card>

  <Card title="Verification" icon="circle-check" href="/sdks/mobile/ios/getting-started/verification">
    Verify your integration
  </Card>

  <Card title="Event Properties" icon="list" href="/sdks/mobile/ios/core-concepts/event-properties">
    Schema requirements
  </Card>
</CardGroup>
