---
title: "Profile Component"
canonical_url: "https://apidocs.sportradar.com/resources/virtual-stadium/docs/ios/profile"
markdown_url: "https://apidocs.sportradar.com/resources/virtual-stadium/docs/ios/profile.md"
last_updated: "2026-06-01T10:35:37Z"
---

# Profile Component

The Profile component displays user information, statistics, and betting activity within the Virtual Stadium community. It shows a user's shared bets, copy count, and engagement metrics, and can be accessed either through the Chat component's user interactions or opened manually.

## Overview

The Profile component provides a detailed view of a user's activity in the Virtual Stadium community:

1. Display the ProfileView when users click on profiles in Chat, or open it manually by initializing `ProfileView` directly
2. Configure with a JWT token, the target user ID, and optional chat settings
3. Show user statistics, bet history, and engagement metrics
4. Handle profile dismissal and navigation
5. Customize appearance to match your Chat component theme

This guide will walk you through each step with code examples and best practices.

> **Info**
>
> **Prerequisites**
>
> - The SDK must be initialized with `Managers.SDK.shared.initialize()`

***

## Basic Integration

### SwiftUI

The Profile component is independent from the Chat component. It can be displayed by providing the `userJWT` and `userId` parameters, either in response to a user interaction in Chat or by initializing it directly anywhere in your app.

**Required Parameters:**

- **`userJWT`** `String` *required* — JWT authentication token required to authenticate the user. This is the same JWT used to initialize the Chat component. The Profile component uses this to log the user in automatically if they are not already authenticated.
- **`userId`** `String` *required* — The unique identifier of the user whose profile to display. This is typically provided by the Chat component's `onOpenProfile` callback, or any user ID known to your app.

**Optional Parameters:**

- **`onCopyBet`** `((BetPayload) -> Void)?` *optional* — Callback invoked when a user copies a bet from the profile. Returns the `BetPayload` to add to your bet slip.
- **`onClose`** `(() -> Void)?` *optional* — Callback invoked when the user closes the profile screen. Use this to handle navigation back to the chat.
- **`chatSettings`** `ChatSettings` *optional* — Customization settings for theming, fonts, icons, and translations. Should match the Chat component settings for visual consistency. Default: `ChatSettings()`

> **Warning**
>
> **Breaking Change**
>
> In a previous version of the SDK, `ProfileView` did not require a JWT token and authentication was handled externally:
>
> ```swift
> // ❌ Old API — no longer supported
> ProfileView(
>     userId: selectedUserId,
>     onCopyBet: { betPayload in ... },
>     onClose: { showProfile = false },
>     chatSettings: ChatSettings()
> )
> ```
>
> `userJWT` is now a required parameter. The Profile component handles authentication internally — if the user is not already logged in, the component will log them in automatically using the provided JWT before displaying the profile content.
>
> ```swift
> // ✅ New API
> ProfileView(
>     userJWT: jwt,
>     userId: selectedUserId,
>     onCopyBet: { betPayload in ... },
>     onClose: { showProfile = false },
>     chatSettings: ChatSettings()
> )
> ```

> **Info**
>
> **Automatic Authentication**
>
> `ProfileView` now manages its own authentication state. When the component appears:
>
> - If the user is **already logged in**, the profile content is displayed immediately.
> - If the user is **not logged in**, the component automatically initiates the login process using the provided JWT and displays a loading indicator until authentication completes.
>
> This means `ProfileView` can be used independently from `ChatView` without requiring a separate login step.

> **Info**
>
> The Profile component is designed to overlay or navigate from the Chat component, but can also be initialized and presented independently anywhere in your application. Use state management to toggle its visibility based on user interactions.

***

### Opening from Chat

The most common use case is opening a profile when a user taps on another user's name or avatar in the Chat component. Use the `onOpenProfileHandler` callback in `ChatViewCallbacksVM` to receive the user ID and present the profile.

**ContentView.swift**

```swift
import SwiftUI
import VirtualStadiumSDK

struct ContentView: View {
    let jwt: String
    let channelId: String
    
    @State private var showProfile = false
    @State private var selectedUserId = ""
    
    var body: some View {
        NavigationView {
            ZStack {
                // Chat component
                ChatView(
                    userJWT: jwt,
                    channelId: channelId,
                    supportedLanguage: .english,
                    callbacksVM: ChatViewCallbacksVM(
                        onCopyToBetslipHandler: { betPayload in
                            print("Bet copied: \(betPayload.id)")
                        },
                        onOpenProfileHandler: { userId in
                            selectedUserId = userId
                            showProfile = true
                        }
                    )
                )
                
                // Profile overlay
                if showProfile {
                    ProfileView(
                        userJWT: jwt,
                        userId: selectedUserId,
                        onCopyBet: { betPayload in
                            print("Bet copied from profile: \(betPayload.id)")
                        },
                        onClose: {
                            showProfile = false
                            selectedUserId = ""
                        },
                        chatSettings: ChatSettings()
                    )
                    .transition(.move(edge: .trailing))
                }
            }
            .navigationTitle("Chat")
            .animation(.easeInOut, value: showProfile)
        }
    }
}
```

***

### Opening Manually

`ProfileView` can also be initialized and presented independently from the Chat component — for example, from a leaderboard, a notification, or any other part of your app where you have a user ID available. Simply provide the same JWT token used elsewhere in your app along with the target user ID.

**StandaloneProfile.swift**

```swift
import SwiftUI
import VirtualStadiumSDK

struct StandaloneProfileExample: View {
    let jwt: String
    let userId: String

    @State private var showProfile = false

    var body: some View {
        Button("View Profile") {
            showProfile = true
        }
        .sheet(isPresented: $showProfile) {
            ProfileView(
                userJWT: jwt,
                userId: userId,
                onCopyBet: { betPayload in
                    /**
                     * TODO(developer): Add bet to user's bet slip
                     */
                    print("Bet copied from profile: \(betPayload.id)")
                },
                onClose: {
                    showProfile = false
                },
                chatSettings: ChatSettings()
            )
        }
    }
}
```

***

## Profile Content

The Profile component displays the following information:

### User Header

- **Display Name** - The user's name in the community
- **Avatar** - User profile picture
- **Close Button** - Dismiss the profile view

### Statistics Section

| Metric          | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| **Bets Shared** | Total number of bet slips the user has shared with the community |
| **Bets Copied** | Number of times other users have copied this user's bets         |

### Bet History

- **Chronological List** - All bet slips shared by the user
- **Bet Details** - Each bet slip shows:
  - Bet type (Single, Multi, Bet Builder, etc.)
  - Markets and outcomes
  - Odds and potential payout
  - Timestamp
- **Copy Action** - Other users can copy bets directly from the profile
- **Load More** - Pagination support for extensive bet histories

***

## Styling and Theming

For a cohesive user experience, use the same `ChatSettings` for both Chat and Profile components. This ensures consistent colors, fonts, and icons throughout your application.

### Shared Settings Configuration

Create a single `ChatSettings` instance and reuse it across both components. This maintains visual consistency and simplifies theme management.

**Best Practice:**

- Define your settings once
- Share across Chat and Profile components
- Update in a single location when styling changes

> **Warning**
>
> Using different `ChatSettings` for Chat and Profile will result in an inconsistent user experience. Always share the same configuration.
