Identify users at registration (iOS)

Identify users at registration (iOS)

The account registered signal is how your iOS app tells Connect that a new user just signed up. The SDK sends an identifier — typically a customer ID or email address — and Connect uses it to create the contact record (or match it to an existing one). Once the contact is known, marketers can trigger onboarding journeys and the rest of the user's session is attributed to that contact. For details on how Connect processes identification records, see How behavior signals are processed in Connect.

Language: Swift. The ConnectIdentity API is not available in Objective-C.

Availability: Pro, Premium, and Ultimate


How identification works

Two parameters do the identification work:

  • identifierName — the contact attribute in Connect that the value should be matched against (for example, Customer ID or Email Address).
  • identifierValue — the value itself.

Everything else on the call (signalType, additionalParameters) is descriptive metadata about how the user registered. It is stored alongside the signal but does not affect contact matching.

Choosing an identifier

Use the most stable identifier your account-creation service returns:

  1. Customer ID (preferred when available). If your Connect audience has a contact key attribute, use it — this is what Connect uses internally to identify a contact. The attribute is often named Customer ID, but in loyalty-driven apps it can be a loyalty number; either way, it points at the same contactKey in your Connect audience.
  2. Email address or phone number. Both are standard channels in Connect and are well-suited for identification when no customer ID is available. Map to the corresponding contact attribute in your Connect audience — commonly named something like "Email Address" or "Phone Number", but the exact name varies by audience.

Populate multiple attributes at registration

identity.log() populates one contact attribute per call. To set more than one — for example, both an email address and a first name on the same contact — call the method once for each attribute, back-to-back, immediately after the account is created. Connect attributes both signals to the same session and resolves them to the same contact.

// First call — primary identifier with full metadata.
ConnectSDK.shared.identity.log(
    identifierName: "Email Address",
    identifierValue: user.email,
    signalType: "accountRegistered",
    additionalParameters: [
        "registrationMethod": "email",
        "registrationSource": "iOS app"
    ]
)

// Second call — sets the contact's first name on the same contact.
ConnectSDK.shared.identity.log(
    identifierName: "First Name",
    identifierValue: user.firstName,
    signalType: "accountRegistered",
    additionalParameters: ["registrationMethod": "email"]
)

Both calls must use the same signalType and additionalParameters must contain the required field — for the account registered signal, that's registrationMethod — even when the second call carries no other metadata.

Use this pattern only for the registration moment itself, when the two calls fire back-to-back in the same authenticated user context. Do not use it to update an attribute later in the user's session, after sign-out, or across a sign-out / sign-in cycle: the session is not tied to your app's auth state, and a later call could resolve to a different contact than you expect.


Before you begin

The identity signal interface is available as soon as the Connect SDK is initialized. No push configuration is required.

let identity = ConnectSDK.shared.identity

Implementation considerations

Registration timing

The account registered signal must fire after the account is created — not when the user submits the sign-up form. For flows that rely on email verification or external identity providers, the signal cannot fire until after the account is confirmed server-side.

Recommended approach: Fire the signal on the post-registration screen or after the account-creation response is confirmed. For SSO-backed registrations, trigger the signal after the callback completes — not during the external provider interaction.

Data sources for identifier value

Several sources of identification are available in iOS apps:

  • Values returned directly from your account creation service
  • Keychain (persistent, survives app reinstall)
  • UserDefaults (persistent, cleared on reinstall)
  • In-memory session state

Wire format

Pass every signal field as a top-level key in additionalParameters — both the required field and any optional fields. The dictionary is flat; do not nest values.

Contact mapping

The identifierName must match a contact attribute name exactly as it appears in Connect, including capitalization and spacing. To look up attribute names, in Connect go to Audience > Contacts > Attributes.


Configuration

Method

ConnectSDK.shared.identity.log(
    identifierName:
    identifierValue:
    signalType:
    additionalParameters:
)

Sends the account registered signal, associating a named identifier with a value.

Parameters

The first two parameters identify the user. The remaining two describe the event.

  • identifierName (String, required) — The contact attribute name this identifier maps to. Must match exactly as it appears in Connect — case sensitive.
  • identifierValue (String, required) — The value of the identifier.
  • signalType (String, required) — Pass "accountRegistered".
  • additionalParameters ([String: String], required) — The signal fields, all as top-level keys. See Supported fields below.

Supported fields in additionalParameters

Required

  • registrationMethod — any string identifying the registration method (for example, email, password, passwordless, sso).

Optional

  • registrationSource — where the registration originated (for example, iOS app, iPad app, referral).
  • name — short label for this signal instance.
  • description — longer human-readable note describing the event.
  • screenViewName — name of the screen where the registration occurred.

Basic example

The examples below use email as the identifier because it's universally available at sign-up. In a production app, prefer a customer ID returned by your account-creation service — see Choosing an identifier above.

ConnectSDK.shared.identity.log(
    identifierName: "Email Address",
    identifierValue: user.email,
    signalType: "accountRegistered",
    additionalParameters: ["registrationMethod": "email"]
)

Complete implementation example

This example fires after a successful sign-up. Call it from your account-creation handler once the account is confirmed server-side. It includes the required field, the optional registrationSource field, and optional envelope fields — name, description, and screenViewName.

func logAccountRegisteredSignal(email: String, registrationMethod: String) {
    ConnectSDK.shared.identity.log(
        identifierName: "Email Address",
        identifierValue: email,
        signalType: "accountRegistered",
        additionalParameters: [
            "registrationMethod": registrationMethod,
            "registrationSource": "iOS app",
            "name": "App account registration",
            "description": "User completed account sign-up in the iOS app.",
            "screenViewName": "AuthViewController"
        ]
    )
}

Call it at the appropriate moment in your sign-up flow:

// After successful account creation
accountService.signUp(email: email, password: password, name: name) { result in
    switch result {
    case .success(let user):
        self.logAccountRegisteredSignal(email: user.email, registrationMethod: "email")
        self.navigateToOnboarding()
    case .failure(let error):
        self.showError(error)
    }
}

Troubleshooting

Signal not appearing in Connect?

  • Verify identifierName and identifierValue are not empty.
  • Confirm additionalParameters includes registrationMethod.
  • Confirm the signal fires after the account is created, not on form submit.
  • Use the SDK debug log to verify the signal is being sent. This requires the debug build of the SDK (for example, the AcousticConnectDebug CocoaPod or the ConnectDebug-SP Swift Package); release builds do not emit these logs. To enable debug logging, add CONNECT_DEBUG, TLF_DEBUG, and EODebug environment variables with a value of 1 to your scheme. Look for a Flushing <Connect.ConnectIdentityMessage: ...> line followed by a Status Code: 200 from the collector.

Contact not created or updated?

  • Verify the identifierName value matches a contact attribute defined in Connect.
  • The SDK accepts only string values for identifierValue and for every entry in additionalParameters. If the matching attribute in Connect is typed as number, Boolean, or date, pass the value as a string representation (for example, "42", "true", or an ISO 8601 date string) and verify in Connect that the value was coerced to the expected type.