Skip to main content
Identity management allows you to track users across different sessions, devices, and platforms by associating multiple identifiers (aliases) with a single user profile.

Overview

A user on a device is automatically allocated a unique device ID by the Permutive SDK on behalf of the publisher. This user ID is distinct across publishers, such that the same user who visits two different publishers' sites on their device will be assigned distinct IDs. As a first-party identity, it does not track users across domains or devices, and it has no reliance on third-party identifiers like cookies or mobile device IDs. The user ID is used in Permutive's cloud to generate accurate publisher-level audience insights, and on-device to store cohort information across sessions.It is also possible to assign users to other IDs, called identifiers, such as an email address the user has authenticated with on the publisher's site, or a third-party identity provided by a partner that the publisher has obtained user consent for. Identifiers can be used to unify the view of a user across multiple devices they use (such as segmenting a user based on their behavior on two different sites owned by the publisher which they are logged in to) or to connect auxiliary data about the user (such as augmenting the segmentation of users with a third-party audience that a partner provides information about). In the iOS SDK, you can set aliases using the setIdentities(aliases:) method. The SDK uses a singleton pattern via Permutive.shared.

Key Concepts

An identifier (formerly called an alias in some SDK and API references) is an alternative identity for a user. Each identifier has:
  • Tag - The type of identifier (e.g., "email_sha256", "internal_id", "aaid")
  • Identity - The actual identifier value
  • Priority - Ordering when multiple identifiers exist (lower number = higher priority)
  • Expiry - Optional expiration date/time
When you set an identifier:
  1. SDK sends the identifier to Permutive servers
  2. Server checks if this identifier is associated with an existing user
  3. If found, user profiles are merged
  4. SDK receives updated cohorts and state
  5. All future events are linked to the resolved identity
Priority determines which identifier is used for identity resolution:
  • Lower number = Higher priority (0 is the highest)
  • Identifiers are resolved in priority order
  • If the highest priority identifier resolves to a user, that identity is used
Priority 0 (Highest): Hashed email - Most reliable, persistent
Priority 1: Internal user ID - Reliable when user is logged in
Priority 2: Advertising ID - Less reliable, can be reset
Priority 3 (Lowest): Device ID - Least reliable

Setting Identity

For apps with a single identifier type:
do {
    let alias = Alias(tag: "internal_id", identity: userId)
    try Permutive.shared.setIdentities(aliases: [alias])
} catch {
    print("Failed to set identity: \(error)")
}

Security Best Practices

Always hash personally identifiable information like email addresses before sending to Permutive.
import CryptoKit

func hashEmail(_ email: String) -> String {
    let normalized = email.trimmingCharacters(in: .whitespaces).lowercased()
    let data = Data(normalized.utf8)
    let hash = SHA256.hash(data: data)
    return hash.compactMap { String(format: "%02x", $0) }.joined()
}

// Usage
let emailHash = hashEmail("[email protected]")
let alias = Alias(tag: "email_sha256", identity: emailHash)
try? Permutive.shared.setIdentities(aliases: [alias])

Standard Tag Names

Identifier TypeRecommended TagNotes
SHA-256 hashed emailemail_sha256Most common
Internal user IDinternal_id or user_idYour system’s ID
Vendor identifieridfvUIDevice.identifierForVendor
Customer IDcustomer_idE-commerce systems
Subscriber IDsubscriber_idSubscription services

Reserved Tags

Some alias tags are reserved by the SDK and cannot be used:
  • appnexus
  • amp
  • gigya
  • sailthru
  • aaid
Aliases with these tags will be ignored.

IDFA Identity

Permutive recommends against using IDFA due to Apple’s App Tracking Transparency requirements. Consider using identifierForVendor or hashed email addresses instead.
If you do need IDFA, use the dedicated setIdentityForIDFA method:
import AdSupport
import AppTrackingTransparency
import Permutive_iOS

func setIDFAIdentity() {
    if #available(iOS 14, *) {
        ATTrackingManager.requestTrackingAuthorization { status in
            guard status == .authorized else { return }

            let idfa = ASIdentifierManager.shared().advertisingIdentifier
            do {
                try Permutive.shared.setIdentityForIDFA(idfa)
            } catch {
                // IDFA may be all zeros (tracking denied)
                print("Failed to set IDFA: \(error)")
            }
        }
    }
}

IDFA Provider Guide

Complete IDFA integration documentation

Retrieving User ID

Get the current Permutive user ID:
let userId = Permutive.shared.currentUserId
print("Permutive User ID: \(userId)")

Tracking User ID Changes

Use TriggerAction to react when the user ID changes:
var userIdTrigger: TriggerAction?

func watchUserIdChanges() {
    userIdTrigger = Permutive.shared.triggerProvider?.actionUpdateForUserIdentity { userId in
        print("User ID changed to: \(userId)")
    }
}

// Release when done
deinit {
    userIdTrigger = nil
}

Common Patterns

func onLoginSuccess(userId: String, email: String) {
    let emailHash = hashEmail(email)

    do {
        let aliases = [
            Alias(tag: "email_sha256", identity: emailHash),
            Alias(tag: "internal_id", identity: userId, priority: 1)
        ]
        try Permutive.shared.setIdentities(aliases: aliases)
    } catch {
        print("Failed to set identity: \(error)")
    }
}
import UIKit
import Permutive_iOS

func setVendorIdentity() {
    guard let idfv = UIDevice.current.identifierForVendor?.uuidString else {
        return
    }

    let alias = Alias(tag: "idfv", identity: idfv, priority: 2)
    try? Permutive.shared.setIdentities(aliases: [alias])
}
class UserManager {
    // User starts as guest (anonymous)
    func onAppLaunch() {
        // SDK automatically creates anonymous ID
        // Optionally set vendor identifier
        setVendorIdentity()
    }

    // User logs in or signs up
    func onUserAuthenticated(userId: String, email: String) {
        let emailHash = hashEmail(email)

        // Permutive merges guest data with authenticated profile
        try? Permutive.shared.setIdentities(aliases: [
            Alias(tag: "email_sha256", identity: emailHash),
            Alias(tag: "internal_id", identity: userId, priority: 1)
        ])
    }
}

Expiry

Aliases can expire automatically, useful for GDPR compliance, session identifiers, and temporary access tokens.
// Never expire (default)
Alias(tag: "email_sha256", identity: emailHash)

// Expire in 30 days
let thirtyDaysFromNow = Date().addingTimeInterval(86400 * 30)
Alias(tag: "session_id", identity: sessionId, expiry: thirtyDaysFromNow)

// Expire at distant future (effectively never)
Alias(tag: "permanent_id", identity: id, expiry: Date.distantFuture)

tvOS Considerations

tvOS Note: Identity management works identically on tvOS. However, IDFA and App Tracking Transparency are not available on tvOS. Use identifierForVendor or hashed email as primary identifiers.

Troubleshooting

Problem: Setting identity doesn’t merge user data across devices.Solutions:
  • Check network connectivity
  • Verify the alias has been used in other sessions/devices
  • Enable debug logging: options.logModes = LogMode.all
  • Look for identity-related logs in the console
Problem: Same user appears as two different users.Solution: Use consistent alias tags and values. When a user logs in on multiple devices, use the same alias (e.g., hashed email).
Problem: Alias with certain tags is ignored.Solution: Avoid reserved tags: appnexus, amp, gigya, sailthru, aaid. Use custom tags instead.

Best Practices

  • Hash PII (especially email addresses) before setting as identity
  • Use meaningful tag names that describe the identifier type
  • Set priorities based on reliability and persistence
  • Use expiry dates for temporary or less reliable identifiers
  • Set identity as early as possible in the user journey
  • Use identifierForVendor as a fallback identifier