View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • App Intents
    • Apple 智能
    • 游戏
    • 机器学习与 AI
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区主导的活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 概要
  • 代码
  • 打造实时沟通体验

    借助 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

    • 了解 App Intents

    WWDC22

    • 利用 Push to Talk 优化语音通信
  • 搜索此视频…
    • 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.

Developer Footer

  • 视频
  • WWDC26
  • 打造实时沟通体验
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • Apple 智能
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • Mini Apps Partner Program
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则