# Contact Data
SDK tracks two types of contacts: anonymous and identified. You start with an anonymous contact and identify them once you have their data - typically at login or registration.
# Create an anonymous contact
Call ping() to create an anonymous contact profile and start collecting data. A good place for this is right after SDK initialization.
UserSDK.default?.ping()
ping() sends device metadata (OS version, app version, device model, screen dimensions) to Positive User and creates a contact if one doesn't exist yet. Once the call completes, UserSDK.default?.userId is populated with the Positive User-generated identifier.
# Identify a contact
Once you have the contact's data - at login, registration, or profile update - call setUserData with any combination of standard attributes:
UserSDK.default?.setUserData([
.firstName: "Jane",
.lastName: "Doe",
.email: "jane@example.com",
.phone: "+1222333444",
.userId: "your-internal-user-id"
])
setUserData calls ping() internally, so you don't need to call it separately. To remove a previously set value, pass nil:
UserSDK.default?.setUserData([.phone: nil])
# Add custom attributes
Send any additional attributes your product tracks:
UserSDK.default?.setCustomUserData([
"plan": "pro",
"signup_source": "organic",
"trial_ends_at": "2024-12-31T00:00:00.000Z"
])
Custom attributes are merged with existing data on every call. To remove a value, pass nil for its key.
# Logout
When a contact logs out, call logout() to clear all stored data and create a fresh anonymous session:
UserSDK.default?.logout { success, error in
// new anonymous contact session is ready
}
WARNING
logout() clears all local data immediately, even if the network request fails. Don't rely on the completion handler to indicate that server-side cleanup succeeded.