Before using any Virtual Stadium UI components, you must initialize the SDK in your iOS application. This guide covers the initialization process and essential configuration steps.
The SDK must be initialized once when your application starts. You can choose between two approaches: using an AppDelegate (traditional approach) or using SwiftUI's lifecycle methods (modern approach).
Create an AppDelegate and initialize the SDK:
AppDelegate.swift:
import UIKit
import VirtualStadiumSDK
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
// Initialize Virtual Stadium SDK
Task {
do {
try await Managers.SDK.shared.initialize()
print("SDK initialized successfully")
} catch {
print("Failed to initialize SDK: \(error)")
}
}
return true
}
}Then register your AppDelegate in your main App struct:
YourApp.swift:
import SwiftUI
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Alternatively, initialize the SDK directly in your App struct using the init() method:
YourApp.swift:
import SwiftUI
import VirtualStadiumSDK
@main
struct YourApp: App {
init() {
// Initialize Virtual Stadium SDK
Task {
do {
try await Managers.SDK.shared.initialize()
print("SDK initialized successfully")
} catch {
print("Failed to initialize SDK: \(error)")
}
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Or use the .task modifier on your root view:
YourApp.swift:
import SwiftUI
import VirtualStadiumSDK
@main
struct YourApp: App {
@State private var isSDKInitialized = false
var body: some Scene {
WindowGroup {
if isSDKInitialized {
ContentView()
} else {
ProgressView("Initializing...")
.task {
do {
try await Managers.SDK.shared.initialize()
isSDKInitialized = true
print("SDK initialized successfully")
} catch {
print("Failed to initialize SDK: \(error)")
}
}
}
}
}
}The initialize() method should be called only once, when your application launches. Calling it multiple times may cause unexpected behavior. The AppDelegate approach (Option 1) is recommended as it follows iOS conventions and ensures initialization happens at the appropriate time in the app lifecycle.
Once the SDK is initialized, you can implement the ChatView component in your SwiftUI views.
Here's a minimal example of implementing the ChatView: ContentView.swift:
import SwiftUI
import VirtualStadiumSDK
struct ContentView: View {
let userJWT: String = "<your-jwt-token>"
let channelId: String = "<your-channel-id>"
var body: some View {
ChatView(
userJWT: userJWT,
channelId: channelId,
supportedLanguage: .english
)
}
}Here's a complete example with all handlers configured: ChatViewContainer.swift:
import SwiftUI
import VirtualStadiumSDK
struct ChatViewContainer: View {
let jwt: String
let channelId: String
let chatSettings: ChatSettings
@StateObject private var viewModel = ChatViewModel()
@State private var showError = false
@State private var errorMessage = ""
var body: some View {
NavigationView {
ChatView(
userJWT: jwt,
channelId: channelId,
matchStatusManager: viewModel.matchStatusManager,
flashBetManager: viewModel.flashBetManager,
insightsManager: viewModel.insightsManager,
supportedLanguage: .english,
onBetShareHandler: { completion in
// Handle bet sharing
viewModel.shareBet { betPayloads in
completion(betPayloads)
}
},
onCopyToBetslip: { betPayload in
// Handle copying bet to betslip
viewModel.copyToBetslip(betPayload)
},
onTagSelected: { tag in
// Handle tag selection
viewModel.handleTagSelection(tag)
},
onReachSupportTeam: { reason in
// Handle support team contact
viewModel.contactSupport(reason: reason)
},
onOpenProfile: { userId in
// Handle profile navigation
viewModel.openProfile(userId: userId)
},
analyticsProvider: viewModel.analyticsProvider,
onError: { error in
errorMessage = error.localizedDescription
showError = true
},
chatSettings: chatSettings
)
.navigationTitle("Chat")
}
.alert("Error", isPresented: $showError) {
Button("OK", role: .cancel) { }
} message: {
Text(errorMessage)
}
}
}
// Example ViewModel
class ChatViewModel: ObservableObject {
var matchStatusManager: MatchStatusManager?
var flashBetManager: FlashBetManager?
var insightsManager: InsightsManager?
var analyticsProvider: AnalyticsProvider?
init() {
// Initialize your managers here
}
func shareBet(completion: @escaping ([BetPayload]) -> Void) {
// Implement bet sharing logic
}
func copyToBetslip(_ betPayload: BetPayload) {
// Implement bet copying logic
}
func handleTagSelection(_ tag: Tag) {
// Implement tag selection logic
}
func contactSupport(reason: InfractionReason) {
// Implement support contact logic
}
func openProfile(userId: String) {
// Implement profile navigation logic
}
}Here's a complete checklist of the initialization and configuration steps:
| Step | Action | Location | Required |
|---|---|---|---|
| 1 | Initialize SDK | AppDelegate or App.init() | ✅ Yes |
| 2 | Register AppDelegate (if using) | Main App struct with @UIApplicationDelegateAdaptor | ⚠️ Only if using Option 1 |
| 3 | Implement ChatView | SwiftUI View | ✅ Yes |
| 4 | Configure handlers | ChatView parameters | ⚠️ Optional but recommended |
If you see an error about the SDK not being initialized:
Managers.SDK.shared.initialize() is called before presenting ChatViewAppDelegate is registered using @UIApplicationDelegateAdaptor (if using Option 1)If your handlers (onBetShareHandler, onCopyToBetslip, etc.) aren't being called:
nilIf you experience timing-related issues with initialization:
Now that the SDK is initialized and configured, you're ready to explore the chat component in detail:
Implement Chat Component
Learn how to add the Chat component to your app with all its parameters, features, and customization options.