Skip to main content

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:

  1. Go to File > Add Package Dependencies...
  2. Enter the repository URL: https://your-repo-url.com/lovina-chat-sdk
  3. Set the version rule (e.g., Up to Next Major Version from 1.0.0)
  4. Select the LovinaChatSDK library 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

ParameterTypeDefaultDescription
websiteTokenStringrequiredWebsite channel token from your Lovina dashboard
baseUrlStringrequiredBase URL of your Lovina instance
localeString"id"Widget locale code (3 languages supported)
colorSchemeString"auto""light", "dark", or "auto"
userLovinaChatUser?nilPre-identified user
customColorUIColor?nilBrand color for theming
displayModeString"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

EventDescription
.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:

  1. Run pnpm dev in the SDK repo
  2. Add packages/ios/ as a local Swift Package in Xcode
  3. Set baseUrl = "http://localhost:3001"
  4. Run on the iOS Simulator

Next Steps