Troubleshooting
| Symptom | What to check |
|---|---|
| Build fails with “No such module ‘ZeotapCollect’”. | Confirm Package Dependencies (SPM) or pod install (CocoaPods) ran cleanly. Run Product → Clean Build Folder then Build. |
| Init runs but no events appear. | Check logging(value: true) console output. Confirm optOut(value: false) and (if consent is in use) that setConsent has been called. |
| Init runs, consent looks fine, still no events. | Open the iOS Source in the Zeotap CDP and watch the PREVIEW tab. If nothing appears, verify the writeKey matches the Source. |
advertising_id is missing in event payloads. | On iOS 14+, ATT permission is required. Call setAdvertisingIdByATTStatus(status:) or setATTStatusAndAdvertisingId(status:advertisingId:) after requestTrackingAuthorization returns. |
| CocoaPods can’t resolve dependencies. | Run pod cache clean --all → pod update → pod install. If still failing, add source "https://github.com/CocoaPods/Specs.git" to your Podfile. |
| App crashes when calling SDK methods. | Confirm Collect.initialize(option:) ran before any other call. Collect.getInstance() returns nil until init completes. |
| PII isn’t being hashed. | Confirm hashIdentities(value: true) is set and the field name is a reserved PII key (email, cellno, loginid, fpuid). Custom identity keys are never hashed. |
FAQ
What versions of iOS does the SDK support?
iOS 12 and above. Xcode 13+ is recommended for SPM compatibility.Where do events end up after they leave the device?
They land in the iOS Source you configured in the Zeotap CDP. From there they’re available to segmentation, calculated attributes, profile lookups, and downstream destinations.Do I need to wait for initialize to complete before calling other methods?
Collect.initialize(option:) returns synchronously, but getInstance() can return nil very briefly during early app launch. Standard practice is to initialize in application(_:didFinishLaunchingWithOptions:) and call SDK methods only after that point.
How do I get the zi for a user?
zi is unique per app install per write key. It persists in UserDefaults until reset via resetZI() or app uninstall.
What’s the difference between setUserProperties and setUserIdentities?
setUserIdentities is for identifiers (email, phone, login ID, CRM ID) that persist across every subsequent event. setUserProperties is for attribute snapshots (age, gender, plan tier).
If you put an identity in setUserProperties, it won’t be cleared by unsetUserIdentities on logout — that’s why we recommend setUserIdentities for identifiers.
What happens to events while the SDK is waiting for consent?
WithuseConsent(value: true) and no consent set, the SDK queues events locally (up to maxCacheSize). Once consent arrives, allowed events are flushed; denied events are dropped.
How big can the local cache get during a network outage?
maxCacheSize controls this — default 100, max 200. Set it higher for poor-connectivity scenarios.
How do I clear all identities on logout?
How do I send the IDFA on iOS 13 and earlier?
You don’t have to — the SDK reads the IDFA automatically on iOS 13 and below. ATT only applies from iOS 14+.Accepted identifiers
The following PII keys are recognized and treated as reserved identifier fields:email— registered email address. Hashed tosha256,sha1,md5(lower + upper).cellno— registered cellular phone number, without country code. Hashed tosha256,sha1,md5.cellno_cc— phone number with country code (e.g.33 1234567890for France). Hashed.loginid— app-specific login ID. Always hashed.- Custom identities —
crmID,ECID,visitorID, etc. Sent as-is (no hashing).
Send only the main cell number — no country codes embedded in the number, no leading
0, no +, (, or ) symbols. To add a new reserved identifier, talk to your Zeotap TAM.Contextual data captured automatically
Every event payload includes:- Device ID / iOS ID
- Telco carrier, network type, OS version
- Device manufacturer, model, version
- Client app name and app version