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

# Initialize Customer Profile

> Register and identify customers in your iOS app

To allow Gameball to track rewards, events, and progress for each user, your app must register or identify the customer after login or during onboarding.\
This step links all Gameball activity to the correct player profile.

***

## 1. Basic Customer Initialization

Use `initializeCustomer` whenever a user logs in, registers, or updates their information.

<div className="security-banner">
  <div className="security-banner-icon">🔒</div>

  <div className="security-banner-content">
    <strong>Secure API Access:</strong> To benefit from v4.1 secure API endpoints, pass the <code>sessionToken</code> parameter when calling methods (required in upcoming SDK v4). This enables automatic routing to v4.1 secure endpoints. <a href="/api-reference/introduction-v4.1">Learn more about v4.1 →</a>
  </div>
</div>

```swift Swift (Completion Handler) theme={null}
import Gameball

do {
    let attributes = CustomerAttributes(
        displayName: "John Doe",
        firstName: "John",
        lastName: "Doe",
        email: "john@example.com",
        mobile: "+1234567890",
        customAttributes: ["favoriteCategory": "electronics"],
        additionalAttributes: ["city": "New York", "country": "USA"]
    )

    let request = try InitializeCustomerRequest(
        customerId: "customer-123",
        email: "john@example.com",
        mobile: "+1234567890",
        customerAttributes: attributes,
        referralCode: "REF123"   // Optional
    )

    GameballApp.getInstance().initializeCustomer(request) { response, errorMessage in
        if let errorMessage = errorMessage {
            print("Gameball initCustomer error: \(errorMessage)")
        } else {
            print("Customer initialized: \(response?.gameballId ?? "")")
        }
    }
} catch {
    print("Validation error: \(error.localizedDescription)")
}
```

```swift Swift(Asyn/Await) theme={null}
import Gameball

Task {
    do {
        let attributes = CustomerAttributes(displayName: "John Doe")
        let request = try InitializeCustomerRequest(
            customerId: "customer-123",
            customerAttributes: attributes
        )

        let response = try await GameballApp.getInstance().initializeCustomer(request)
        print("Customer initialized: \(response.gameballId)")
    } catch {
        print("Error: \(error.localizedDescription)")
    }
}
```

***

## 2. Request Parameters

<ParamField body="customerId" type="String" required>
  Permanent unique identifier for the customer. **Should never change.**
</ParamField>

<ParamField body="email" type="String">
  Customer email address.
</ParamField>

<ParamField body="mobile" type="String">
  Mobile number formatted with country code.
</ParamField>

<ParamField body="deviceToken" type="String">
  Push notification token (Firebase FCM or Huawei Push Kit).
</ParamField>

<ParamField body="pushProvider" type="PushProvider">
  Push provider (`.firebase` or `.huawei`).
</ParamField>

<ParamField body="customerAttributes" type="CustomerAttributes">
  Structured attributes such as name, DOB, language, and custom fields.
</ParamField>

<ParamField body="referralCode" type="String">
  Referral code used when registering a referred customer.
</ParamField>

<ParamField body="isGuest" type="Bool">
  Indicates if this user is a guest session (default: false).
</ParamField>

<ParamField body="sessionToken" type="String">
  Optional override for global session token for this request only. Required in upcoming SDK v4.
</ParamField>

***

## 3. Validation Rules

InitializeCustomerRequest validates:

* customerId cannot be empty
* If pushProvider is provided → deviceToken is required
* If deviceToken is provided → pushProvider is required

If validation fails, the SDK returns an error before sending the request.

***

## 4. Customer Attributes

You can enrich customer profiles with additional metadata.

<Expandable title="CustomerAttributes Properties">
  <ParamField body="displayName" type="String">
    Customer's display name.
  </ParamField>

  <ParamField body="firstName" type="String">
    First name.
  </ParamField>

  <ParamField body="lastName" type="String">
    Last name.
  </ParamField>

  <ParamField body="email" type="String">
    Email address.
  </ParamField>

  <ParamField body="mobile" type="String">
    Mobile number.
  </ParamField>

  <ParamField body="gender" type="String">
    "M" or "F".
  </ParamField>

  <ParamField body="dateOfBirth" type="String">
    Format: YYYY-MM-DD.
  </ParamField>

  <ParamField body="joinDate" type="String">
    Format: YYYY-MM-DD.
  </ParamField>

  <ParamField body="preferredLanguage" type="String">
    Language code.
  </ParamField>

  <ParamField body="customAttributes" type="[String: String]">
    Custom key-value pairs.
  </ParamField>

  <ParamField body="additionalAttributes" type="[String: String]">
    Extra metadata fields.
  </ParamField>
</Expandable>

***

## 5. Advanced Examples

### With Push Notifications

```swift theme={null}
import Gameball
import UserNotifications

// Ask for notification permission
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
    if granted {
        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}

func application(
    _ application: UIApplication,
    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()

    do {
        let request = try InitializeCustomerRequest(
            customerId: "customer-123",
            deviceToken: token,
            pushProvider: .firebase
        )

        GameballApp.getInstance().initializeCustomer(request) { _, _ in }
    } catch {
        print("Token validation error: \(error.localizedDescription)")
    }
}
```

***

### With Referral Code

```swift theme={null}
func registerCustomerWithReferral(customerId: String, referralCode: String) {
    do {
        let request = try InitializeCustomerRequest(
            customerId: customerId,
            referralCode: referralCode
        )

        GameballApp.getInstance().initializeCustomer(request) { _, _ in }
    } catch {
        print("Validation error: \(error.localizedDescription)")
    }
}
```

***

### Guest User

```swift theme={null}
func initializeGuestUser(sessionId: String) {
    do {
        let request = try InitializeCustomerRequest(
            customerId: "guest_\(sessionId)",
            isGuest: true
        )

        GameballApp.getInstance().initializeCustomer(request) { _, _ in }
    } catch {
        print("Validation error: \(error.localizedDescription)")
    }
}
```

***

### Full Customer Profile Example

```swift theme={null}
func initializeFullProfile() {
    do {
        let attributes = CustomerAttributes(
            displayName: "John Doe",
            firstName: "John",
            lastName: "Doe",
            email: "john@example.com",
            mobile: "+1234567890",
            gender: "M",
            dateOfBirth: "1990-01-15",
            joinDate: "2024-01-01",
            preferredLanguage: "en"
        )

        attributes.customAttributes = [
            "favoriteCategory": "electronics"
        ]

        attributes.additionalAttributes = [
            "segment": "premium",
            "source": "ios_app",
            "city": "New York",
            "country": "USA"
        ]

        let request = try InitializeCustomerRequest(
            customerId: "customer-123",
            email: "john@example.com",
            mobile: "+1234567890",
            customerAttributes: attributes
        )

        GameballApp.getInstance().initializeCustomer(request) { _, _ in }
    } catch {
        print("Validation error: \(error.localizedDescription)")
    }
}
```

<Warning>
  **Use a permanent, unchanging customer ID.**\
  Do NOT use email or phone number as they can change.
</Warning>

<Tip>
  Call `initializeCustomer` immediately after successful login or registration so Gameball can keep the profile updated.
</Tip>
