Quick Start: iOS
Embed the Lovina chat widget in your iOS app using a Swift WKWebView wrapper. Minimum deployment target: iOS 15.0.
Step 1: Install via Swift Package Manager
In Xcode:
- Go to File > Add Package Dependencies...
- Enter the repository URL:
https://your-repo-url.com/lovina-chat-sdk - Set the version rule (e.g., Up to Next Major Version from
1.0.0) - Select the
LovinaChatSDKlibrary and add it to your target
Or add it to your Package.swift:
dependencies: [
.package(url: "https://your-repo-url.com/lovina-chat-sdk", from: "1.0.0")
]
Then add the product to your target:
.target(
name: "YourApp",
dependencies: [
.product(name: "LovinaChatSDK", package: "lovina-chat-sdk")
]
)
Step 2: UIKit Integration
import UIKit
import LovinaChatSDK
class ChatViewController: UIViewController {
private let chatWidget = LovinaChatWidget()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(chatWidget)
chatWidget.frame = view.bounds
chatWidget.autoresizingMask = [.flexibleWidth, .flexibleHeight]
chatWidget.onEvent = { event in
switch event {
case .loaded(let authToken):
print("Widget loaded, token: \(authToken ?? "none")")
case .messageReceived(let message):
print("New message: \(message)")
case .unreadCountChanged(let count):
self.updateBadge(count)
case .closed:
self.dismiss(animated: true)
case .error(let code, let message):
print("Error [\(code)]: \(message)")
}
}
chatWidget.configure(LovinaChatConfig(
websiteToken: "your-website-token",
baseUrl: "https://chat.lovina.app"
))
}
deinit {
chatWidget.destroy()
}
}
Step 3: SwiftUI Integration
import SwiftUI
import LovinaChatSDK
struct ChatScreen: View {
var body: some View {
LovinaChatView(
config: LovinaChatConfig(
websiteToken: "your-website-token",
baseUrl: "https://chat.lovina.app"
),
onEvent: { event in
switch event {
case .messageReceived(let message):
print("New message: \(message)")
default:
break
}
}
)
.edgesIgnoringSafeArea(.all)
}
}
Configuration Options
| Parameter | Type | Default | Description |
|---|---|---|---|
websiteToken | String | required | Website channel token from your Lovina dashboard |
baseUrl | String | required | Base URL of your Lovina instance |
locale | String | "id" | Widget locale code (3 languages supported) |
colorScheme | String | "auto" | "light", "dark", or "auto" |
user | LovinaChatUser? | nil | Pre-identified user |
customColor | UIColor? | nil | Brand color for theming |
displayMode | String | "fullscreen" | "popup", "sidebar", or "fullscreen" |
Pre-identified Users
Associate chat sessions with known users:
let config = LovinaChatConfig(
websiteToken: "your-token",
baseUrl: "https://chat.lovina.app",
user: LovinaChatUser(
identifier: "user-12345",
name: "Jane Doe",
email: "jane@example.com",
phoneNumber: "+6281234567890",
identifierHash: "hmac-hash-for-verification",
customAttributes: [
"plan": "premium",
"signup_date": "2025-01-15"
]
)
)
White-Label Theming
Apply a custom brand color:
let config = LovinaChatConfig(
websiteToken: "your-token",
baseUrl: "https://chat.lovina.app",
customColor: UIColor(red: 0.39, green: 0.40, blue: 0.95, alpha: 1.0)
)
The SDK automatically adjusts text contrast based on whether your color is light or dark.
Event Handling
| Event | Description |
|---|---|
.loaded(authToken) | Widget finished loading. authToken is available if the user has a session. |
.messageReceived(message) | New message received. message is a dictionary with the payload. |
.unreadCountChanged(count) | Unread count changed. Use count to update a badge. |
.closed(reason) | Chat was closed by user or agent. |
.error(code, message) | An error occurred. |
Session Management
Sessions are persisted automatically in the Keychain. To clear a session:
chatWidget.clearSession()
chatWidget.reload()
Lifecycle
The widget cleans up automatically in deinit. You may also call destroy() explicitly:
deinit {
chatWidget.destroy()
}
Network connectivity is monitored via NWPathMonitor. The widget handles offline/online transitions automatically.
Development Setup
To test against your local dev server:
- Run
pnpm devin the SDK repo - Add
packages/ios/as a local Swift Package in Xcode - Set
baseUrl = "http://localhost:3001" - Run on the iOS Simulator