-
Créez des expériences de communication en temps réel
LiveCommunicationKit transforme vos apps de communication en temps réel en expériences intégrées. Nous vous montrons comment offrir une interface de conversation native et riche qui place votre app exactement là où les utilisateurs en ont besoin : de la présentation en plein écran sur l'écran verrouillé à une expérience multitâche fluide avec Dynamic Island. Rejoignez-nous pour découvrir l'intégration étape par étape du framework pour les conversations entrantes, sortantes et de groupe.
Chapitres
- 0:01 - Introduction
- 7:56 - Conversations entrantes
- 11:29 - Conversations sortantes
- 13:18 - Groupes
Ressources
- Initiating VoIP conversations with LiveCommunicationKit
- Responding to VoIP Notifications from PushKit
- LiveCommunicationKit
Vidéos connexes
WWDC25
WWDC22
-
Rechercher dans cette vidéo…
-
-
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() } } } }
-