Swift SDK

ElevenAgents SDK: अपने Swift एप्लिकेशन में कस्टमाइज़्ड, इंटरैक्टिव वॉइस एजेंट डिप्लॉय करें।

एक पूरे काम करने वाले उदाहरण के साथ तेज़ी से शुरुआत करने के लिए हमारा पूरा Swift क्विकस्टार्ट प्रोजेक्ट देखें।

इंस्टॉलेशन

Swift Package Manager का इस्तेमाल करके अपने प्रोजेक्ट में ElevenLabs Swift SDK जोड़ें:

1

पैकेज डिपेंडेंसी जोड़ें

dependencies: [ .package(url: "https://github.com/elevenlabs/elevenlabs-swift-sdk.git",
from: "2.0.0") ]

या Xcode का इस्तेमाल करके:

  1. अपना प्रोजेक्ट Xcode में खोलें
  2. File > Add Package Dependencies... पर जाएं
  3. रिपॉज़िटरी URL डालें: https://github.com/elevenlabs/elevenlabs-swift-sdk.git
  4. वर्ज़न 2.0.0 या नया चुनें
2

SDK इंपोर्ट करें

import ElevenLabs

माइक्रोफ़ोन एक्सेस के बारे में यूज़र्स को बताने के लिए अपने Info.plist में NSMicrophoneUsageDescription जोड़ना सुनिश्चित करें। SDK के लिए iOS 14.0+ / macOS 11.0+ और Swift 5.9+ चाहिए।

क्विक स्टार्ट

कुछ ही लाइनों में एक आसान बातचीत शुरू करें। वैकल्पिक रूप से, बातचीत को अपने यूज़र्स से मैप करने के लिए हम आपके अपने एंड यूज़र IDs पास करने की सलाह देते हैं।

import ElevenLabs
// Start a conversation with your agent
let conversation = try await ElevenLabs.startConversation(
agentId: "your-agent-id",
userId: "your-end-user-id",
config: ConversationConfig()
)
// Observe conversation state and messages
conversation.$state
.sink { state in
print("Connection state: \(state)")
}
.store(in: &cancellables)
conversation.$messages
.sink { messages in
for message in messages {
print("\(message.role): \(message.content)")
}
}
.store(in: &cancellables)
// Send messages and control the conversation
try await conversation.sendMessage("Hello!")
try await conversation.toggleMute()
await conversation.endConversation()

ऑथेंटिकेशन

ऑथेंटिकेट करने और बातचीत शुरू करने के दो तरीके हैं:

पब्लिक एजेंट्स के लिए, सीधे एजेंट ID का इस्तेमाल करें:

let conversation = try await ElevenLabs.startConversation(
agentId: "your-public-agent-id",
config: ConversationConfig()
)

मुख्य सुविधाएं

रिएक्टिव बातचीत प्रबंधन

SDK रिएक्टिव UI अपडेट्स के लिए @Published प्रॉपर्टीज़ के साथ एक आधुनिक Conversation क्लास देता है:

@MainActor
class ConversationManager: ObservableObject {
@Published var conversation: Conversation?
private var cancellables = Set<AnyCancellable>()
func startConversation(agentId: String) async throws {
let config = ConversationConfig(
conversationOverrides: ConversationOverrides(textOnly: false)
)
conversation = try await ElevenLabs.startConversation(
agentId: agentId,
config: config
)
setupObservers()
}
private func setupObservers() {
guard let conversation else { return }
// Monitor connection state
conversation.$state
.sink { state in print("State: \(state)") }
.store(in: &cancellables)
// Monitor messages
conversation.$messages
.sink { messages in print("Messages: \(messages.count)") }
.store(in: &cancellables)
}
}

वॉइस और टेक्स्ट मोड्स

// Voice conversation (default)
let voiceConfig = ConversationConfig(
conversationOverrides: ConversationOverrides(textOnly: false)
)
// Text-only conversation
let textConfig = ConversationConfig(
conversationOverrides: ConversationOverrides(textOnly: true)
)

ऑडियो कंट्रोल्स

// Microphone control
try await conversation.toggleMute()
try await conversation.setMuted(true)
// Check microphone state
let isMuted = conversation.isMuted
// Access audio tracks for advanced use cases
let inputTrack = conversation.inputTrack
let agentAudioTrack = conversation.agentAudioTrack

क्लाइंट टूल्स

क्लाइंट टूल्स आपको कस्टम फ़ंक्शंस रजिस्टर करने देते हैं, जिन्हें आपका AI एजेंट बातचीत के दौरान कॉल कर सकता है। नया SDK बेहतर पैरामीटर हैंडलिंग और एरर मैनेजमेंट देता है।

टूल कॉल्स हैंडल करना

पूरे पैरामीटर सपोर्ट के साथ अपने एजेंट से आने वाली टूल कॉल्स हैंडल करें:

private func handleToolCall(_ toolCall: ClientToolCallEvent) async {
do {
let parameters = try toolCall.getParameters()
let result = await executeClientTool(
name: toolCall.toolName,
parameters: parameters
)
if toolCall.expectsResponse {
try await conversation?.sendToolResult(
for: toolCall.toolCallId,
result: result
)
} else {
conversation?.markToolCallCompleted(toolCall.toolCallId)
}
} catch {
// Handle tool execution errors
if toolCall.expectsResponse {
try? await conversation?.sendToolResult(
for: toolCall.toolCallId,
result: ["error": error.localizedDescription],
isError: true
)
}
}
}
// Example tool implementation
func executeClientTool(name: String, parameters: [String: Any]) async -> [String: Any] {
switch name {
case "get_weather":
guard let location = parameters["location"] as? String else {
return ["error": "Missing location parameter"]
}
// Fetch weather data
return ["temperature": "22°C", "condition": "Sunny"]
case "send_email":
guard let recipient = parameters["recipient"] as? String,
let subject = parameters["subject"] as? String else {
return ["error": "Missing required parameters"]
}
// Send email logic
return ["status": "sent", "messageId": "12345"]
default:
return ["error": "Unknown tool: \(name)"]
}
}

ElevenLabs UI में अपने एजेंट को client-tools के साथ सेट अप करना याद रखें। सेटअप निर्देशों के लिए क्लाइंट टूल्स दस्तावेज़ देखें।

कनेक्शन स्टेट मैनेजमेंट

अलग-अलग कनेक्शन चरणों को हैंडल करने के लिए बातचीत का स्टेट मॉनिटर करें:

conversation.$state
.sink { state in
switch state {
case .idle:
// Not connected
break
case .connecting:
// Show connecting indicator
break
case .active(let callInfo):
// Connected to agent: \(callInfo.agentId)
break
case .ended(let reason):
// Handle disconnection: \(reason)
break
case .error(let error):
// Handle error: \(error)
break
}
}
.store(in: &cancellables)

एजेंट स्टेट मॉनिटरिंग

ट्रैक करें कि एजेंट कब सुन रहा है या बोल रहा है:

conversation.$agentState
.sink { state in
switch state {
case .listening:
// Agent is listening, show listening indicator
break
case .speaking:
// Agent is speaking, show speaking indicator
break
}
}
.store(in: &cancellables)

मैसेज हैंडलिंग

टेक्स्ट मैसेज भेजें और बातचीत मॉनिटर करें:

// Send a text message
try await conversation.sendMessage("Hello, how can you help me today?")
// Monitor all messages in the conversation
conversation.$messages
.sink { messages in
for message in messages {
switch message.role {
case .user:
print("User: \(message.content)")
case .agent:
print("Agent: \(message.content)")
}
}
}
.store(in: &cancellables)

ऑडियो अलाइनमेंट

सिंक्रनाइज़्ड टेक्स्ट डिस्प्ले के लिए कैरेक्टर-लेवल टाइमिंग डेटा मॉनिटर करें:

// Using the callback
let config = ConversationConfig(
onAudioAlignment: { alignment in
// Character-level timing data
for (index, char) in alignment.chars.enumerated() {
let startMs = alignment.charStartTimesMs[index]
let durationMs = alignment.charDurationsMs[index]
print("'\(char)' at \(startMs)ms for \(durationMs)ms")
}
}
)
// Or observe the published property
conversation.$latestAudioAlignment
.compactMap { $0 }
.sink { alignment in
// Handle alignment updates
}
.store(in: &cancellables)

सेशन मैनेजमेंट

// End the conversation
await conversation.endConversation()
// Check if conversation is active
let isActive = conversation.state.isActive

SwiftUI इंटीग्रेशन

नए SDK का इस्तेमाल करने वाला एक विस्तृत SwiftUI उदाहरण यहां दिया गया है:

import SwiftUI
import ElevenLabs
import Combine
struct ConversationView: View {
@StateObject private var viewModel = ConversationViewModel()
var body: some View {
VStack(spacing: 20) {
// Connection status
Text(viewModel.connectionStatus)
.font(.headline)
.foregroundColor(viewModel.isConnected ? .green : .red)
// Chat messages
ScrollView {
LazyVStack(alignment: .leading, spacing: 8) {
ForEach(viewModel.messages, id: \.id) { message in
MessageBubble(message: message)
}
}
}
.frame(maxHeight: 400)
// Controls
HStack(spacing: 16) {
Button(viewModel.isConnected ? "End" : "Start") {
Task {
if viewModel.isConnected {
await viewModel.endConversation()
} else {
await viewModel.startConversation()
}
}
}
.buttonStyle(.borderedProminent)
Button(viewModel.isMuted ? "Unmute" : "Mute") {
Task { await viewModel.toggleMute() }
}
.buttonStyle(.bordered)
.disabled(!viewModel.isConnected)
Button("Send Message") {
Task { await viewModel.sendTestMessage() }
}
.buttonStyle(.bordered)
.disabled(!viewModel.isConnected)
}
// Agent state indicator
if viewModel.isConnected {
HStack {
Circle()
.fill(viewModel.agentState == .speaking ? .blue : .gray)
.frame(width: 10, height: 10)
Text(viewModel.agentState == .speaking ? "Agent speaking" : "Agent listening")
.font(.caption)
}
}
}
.padding()
}
}
struct MessageBubble: View {
let message: Message
var body: some View {
HStack {
if message.role == .user { Spacer() }
VStack(alignment: .leading) {
Text(message.role == .user ? "You" : "Agent")
.font(.caption)
.foregroundColor(.secondary)
Text(message.content)
.padding()
.background(message.role == .user ? Color.blue : Color.gray.opacity(0.3))
.foregroundColor(message.role == .user ? .white : .primary)
.cornerRadius(12)
}
if message.role == .agent { Spacer() }
}
}
}
@MainActor
class ConversationViewModel: ObservableObject {
@Published var messages: [Message] = []
@Published var isConnected = false
@Published var isMuted = false
@Published var agentState: AgentState = .listening
@Published var connectionStatus = "Disconnected"
private var conversation: Conversation?
private var cancellables = Set<AnyCancellable>()
func startConversation() async {
do {
conversation = try await ElevenLabs.startConversation(
agentId: "your-agent-id",
config: ConversationConfig()
)
setupObservers()
} catch {
print("Failed to start conversation: \(error)")
connectionStatus = "Failed to connect"
}
}
func endConversation() async {
await conversation?.endConversation()
conversation = nil
cancellables.removeAll()
}
func toggleMute() async {
try? await conversation?.toggleMute()
}
func sendTestMessage() async {
try? await conversation?.sendMessage("Hello from the app!")
}
private func setupObservers() {
guard let conversation else { return }
conversation.$messages
.assign(to: &$messages)
conversation.$state
.map { state in
switch state {
case .idle: return "Disconnected"
case .connecting: return "Connecting..."
case .active: return "Connected"
case .ended: return "Ended"
case .error: return "Error"
}
}
.assign(to: &$connectionStatus)
conversation.$state
.map { $0.isActive }
.assign(to: &$isConnected)
conversation.$isMuted
.assign(to: &$isMuted)
conversation.$agentState
.assign(to: &$agentState)
}
}