-
打造实时沟通体验
借助 LiveCommunicationKit,让你的实时通信 App 大变身,为用户带来深度整合的沟通体验。我们将介绍如何提供丰富的原生对话 UI,让你的 App 出现在恰如用户所需的地方,比如全屏显示在锁定屏幕上,以及通过灵动岛实现丝滑的多任务处理。与我们一起逐步了解如何整合这一消息收发和群组对话框架。
章节
- 0:01 - Introduction
- 7:56 - Incoming conversations
- 11:29 - Outgoing conversations
- 13:18 - Groups
资源
- Initiating VoIP conversations with LiveCommunicationKit
- Responding to VoIP Notifications from PushKit
- LiveCommunicationKit
相关视频
WWDC25
WWDC22
-
搜索此视频…
-
-
6:41 - Set up a conversation manager
// Set up a conversation manager import LiveCommunicationKit let configuration = ConversationManager.Configuration( ringtoneName: "SampleRingtone.caf", iconTemplateImageData: UIImage(named: "SampleIcon")?.pngData(), maximumConversationGroups: 1, maximumConversationsPerConversationGroup: 2, includesConversationInRecents: true, supportsVideo: true, supportedHandleTypes: [.phoneNumber, .emailAddress] ) let manager = ConversationManager(configuration: configuration) manager.delegate = self -
9:22 - Report the incoming conversation to the system
// Report the incoming conversation to the system import LiveCommunicationKit import PushKit final class SamplePushHandler: NSObject, PKPushRegistryDelegate { func pushRegistry( _ registry: PKPushRegistry, didReceiveIncomingVoIPPushWith payload: PKPushPayload, metadata: PKVoIPPushMetadata) async { guard let (handle, uuid) = parseConversationPayload(from: payload) else { return } let capabilities = [.video, .pausing, .merging] let update = Conversation.Update(members: [handle], capabilities: capabilities) try? await manager.reportNewIncomingConversation(uuid: uuid, update: update) } } -
9:57 - Implement the delegate
// Implement the delegate import LiveCommunicationKit final class SampleDelegate: ConversationManagerDelegate { func conversationManager( _ manager: ConversationManager, perform action: ConversationAction ) { switch action { case let action as JoinConversationAction: handleJoinAction(action) default: action.fail() } } } -
10:13 - Fulfill the join action
// Handle a failed connection extension SampleDelegate { func handleJoinAction(_ action: JoinConversationAction) { guard let conversation = manager.conversations.first(where: {$0.uuid == uuid })else { return action.fail() } manager.reportConversationEvent(.conversationStartedConnecting(.now), for: conversation) Task { do { try await setupMediaStream(with: action.conversationUUID) manager.reportConversationEvent(.conversationConnected(.now), for: conversation) action.fulfill(dateConnected: .now) } catch { action.fail() } } } } -
11:17 - Route end actions
// Route end actions final class SampleDelegate: ConversationManagerDelegate { // … func conversationManager( _ manager: ConversationManager, perform action: ConversationAction ) { switch action { case let action as JoinConversationAction: handleJoinAction(action) case let action as EndConversationAction: handleEndAction(action) default: action.fail() } } } -
12:14 - Create a start action
let startAction = StartConversationAction( conversationUUID: UUID(), handles: [Handle(type: .phoneNumber, value: "+1-650-555-0199", displayName: "Ryan Notch")], isVideo: false ) -
12:23 - Perform the action
try await manager.perform([startAction]) -
12:29 - Route start actions
// Route start actions final class SampleDelegate: ConversationManagerDelegate { // … func conversationManager( _ manager: ConversationManager, perform action: ConversationAction ) { switch action { case let action as JoinConversationAction: handleJoinAction(action) case let action as EndConversationAction: handleEndAction(action) case let action as StartConversationAction: handleStartAction(action) default: action.fail() } } } -
13:51 - Start group conversations
// Start group conversations let adam = Handle(type: .emailAddress, value: "adam.halwani@icloud.com", displayName: "Adam Halwani") let david = Handle(type: .emailAddress, value: "david@example.com", displayName: "David Evans") let ryan = Handle(type: .phoneNumber, value: "+16505550199", displayName: "Ryan Notch") let startAction = StartConversationAction( conversationUUID: UUID(), handles: [david, ryan], isVideo: false ) try await manager.perform([startAction]) -
14:01 - Report group membership updates
// Report group membership updates let update = Conversation.Update( localMember: adam, members: [david, ryan], activeRemoteMembers: [david, ryan], capabilities: [.merging, .pausing, .unmerging] ) manager.reportConversationEvent( .conversationUpdated(update), for: conversation ) -
15:26 - Route merge actions
// Route merge actions final class SampleDelegate: ConversationManagerDelegate { func conversationManager( _ manager: ConversationManager, perform action: ConversationAction ) { switch action { case let action as JoinConversationAction: handleJoinAction(action) case let action as EndConversationAction: handleEndAction(action) case let action as StartConversationAction: handleStartAction(action) case let action as MergeConversationAction: handleMergeAction(action) default: action.fail() } } } -
15:33 - Handle the merge action
// Handle the merge action extension SampleDelegate { func handleMergeAction(_ action: MergeConversationAction) { let sourceUUID = action.conversationUUID let targetUUID = action.conversationUUIDToMergeWith guard manager.conversations.contains(where: { $0.uuid == sourceUUID }), manager.conversations.contains(where: { $0.uuid == targetUUID }) else { return action.fail() } Task { do { let update = try await combineStreams(from: sourceUUID, into: targetUUID) manager.reportConversationEvent(.conversationUpdated(update), for: target) action.fulfill() } catch { action.fail() } } } }
-
-
- 0:01 - Introduction
LiveCommunicationKit is the modern way to build live conversation experiences that integrate with the system. Conversations in LiveCommunicationKit are built upon fundamental elements, such as handles, display names, and capabilities, that configure the interface, as well as a single ConversationManager object to manage the full lifecycle.
- 7:56 - Incoming conversations
Incoming conversations rely on the ConversationManager class where you configure properties like ringtones, group limits, and supported handles. Use PushKit to deliver an incoming conversation to a device, then report it to the ConversationManager.
- 11:29 - Outgoing conversations
Start outgoing conversations initiated within the app by performing a StartConversationAction. This allows your app's ConversationManager delegate to handle the entire process, using the same unified action-handling logic for actions started by in-app or system UI.
- 13:18 - Groups
Track the full list of invited members in addition to the currently active remote members so the interface stays perfectly in sync as people join or drop off. Advanced call management is handled through delegate actions and supports merging and unmerging calls as needed.