diff --git a/markdown/chatroom/AUIVoiceRoom/input-ios.md b/markdown/chatroom/AUIVoiceRoom/input-ios.md new file mode 100644 index 00000000000..97f44ba0513 --- /dev/null +++ b/markdown/chatroom/AUIVoiceRoom/input-ios.md @@ -0,0 +1,225 @@ + + +### 1. 初始化VoiceChatUIKit + +#### 设置依赖库 + +在AppDelegate.swift里设置依赖库 +```swift +import AUIKitCore +import AScenesKit +``` +#### 初始化 + +在AppDelegate.swift里初始化VoiceChatUIKit +```swift +func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + let uid = Int(arc4random_uniform(99999999)) + let commonConfig = AUICommonConfig() + commonConfig.host = "https://service.agora.io/uikit-VoiceChat" + commonConfig.userId = "\(uid)" + commonConfig.userName = "user_\(uid)" + commonConfig.userAvatar = "https://accktvpic.oss-cn-beijing.aliyuncs.com/pic/sample_avatar/sample_avatar_1.png" + VoiceChatUIKit.shared.setup(roomConfig: commonConfig, + rtcEngine: nil, //如果有外部初始化的rtc engine + rtmClient: nil) //如果有外部初始化的rtm client + // Override point for customization after application launch. + return true +} +``` + +### 2. 房主创建房间 + +#### 添加“创建房间”按钮 + +1. 在ViewController.swift里设置依赖 + ```swift + import AUIKitCore + import AScenesKit + ``` + +2. 添加“创建房间”按钮 + + ```swift + override func viewDidLoad() { + super.viewDidLoad() + + //作为房主创建房间的按钮 + let createButton = UIButton(frame: CGRect(x: 10, y: 100, width: 100, height: 60)) + createButton.setTitle("创建房间", for: .normal) + createButton.setTitleColor(.red, for: .normal) + createButton.addTarget(self, action: #selector(onCreateAction), for: .touchUpInside) + view.addSubview(createButton) + } + ``` +#### 创建VoiceChat房间 + +```swift +@objc func onCreateAction(_ button: UIButton) { + let roomId = Int(arc4random_uniform(99999999)) + let room = AUICreateRoomInfo() + room.roomName = "\(roomId)" + button.isEnabled = false + VoiceChatUIKit.shared.createRoom(roomInfo: room) { roomInfo in + self.enterRoom(roomInfo: roomInfo!) + button.isEnabled = true + } failure: { error in + print("on create room fail: \(error.localizedDescription)") + button.isEnabled = true + } +} +``` + +### 3.进入房间 + +#### 声明属性 + +ViewController里声明一个VoiceChat房间容器的属性 + +```swift +class ViewController: UIViewController { + var VoiceChatView: AUIVoiceChatRoomView? + + .... +} +``` + +#### 创建并启动 + +创建房间详情页并启动VoiceChat房间 + +```swift +func enterRoom(roomInfo: AUIRoomInfo) { + VoiceChatView = AUIVoiceChatRoomView(frame: self.view.bounds) + VoiceChatView!.onClickOffButton = { [weak self] in + //房间内点击退出 + self?.destroyRoom() + } + if let roomView = self.VoiceChatView { + VoiceChatUIKit.shared.launchRoom(roomInfo: roomInfo, + roomView: roomView) {[weak self] error in + guard let self = self else {return} + if let _ = error { return } + //订阅房间被销毁回调 + VoiceChatUIKit.shared.bindRespDelegate(delegate: self) + self.view.addSubview(roomView) + } + } +} +``` + +### 4. 观众进入房间准备(可选) + +#### 添加“加入房间”按钮 + +```swift +override func viewDidLoad() { + super.viewDidLoad() + + //作为观众加入房间的按钮 + let joinButton = UIButton(frame: CGRect(x: 10, y: 160, width: 100, height: 60)) + joinButton.setTitle("加入房间", for: .normal) + joinButton.setTitleColor(.red, for: .normal) + joinButton.addTarget(self, action: #selector(onJoinAction), for: .touchUpInside) + view.addSubview(joinButton) +} +``` + +#### 获取VoiceChat房间信息 + +```swift +@objc func onJoinAction() { + let alertController = UIAlertController(title: "房间名", message: "", preferredStyle: .alert) + alertController.addTextField { (textField) in + textField.placeholder = "请输入" + } + let cancelAction = UIAlertAction(title: "取消", style: .cancel) { (_) in + } + let saveAction = UIAlertAction(title: "确认", style: .default) { (_) in + if let inputText = alertController.textFields?.first?.text { + // 处理用户输入的内容 + VoiceChatUIKit.shared.getRoomInfoList(lastCreateTime: nil, pageSize: 50) { error, roomList in + guard let roomList = roomList else {return} + for room in roomList { + if room.roomName == inputText { + self.enterRoom(roomInfo: room) + break + } + } + } + } + } + alertController.addAction(cancelAction) + alertController.addAction(saveAction) + + present(alertController, animated: true, completion: nil) +} +``` + + + +### 5. 退出/销毁房间 + +#### 设置退出方法 + +1. 设置退出方法 + + ```swift + func destroyRoom(roomId: String) { + //点击退出 + self.VoiceChatView?.onBackAction() + self.VoiceChatView?.removeFromSuperview() + + VoiceChatUIKit.shared.destoryRoom(roomId: roomId) + //在退出房间时取消订阅 + VoiceChatUIKit.shared.unbindRespDelegate(delegate: self) + } + ``` + +2. 主动退出。在上一步创建VoiceChatView时设置回调,即可主动退出房间 + + ```swift + //AUIVoiceChatRoomView提供了onClickOffButton点击返回的clousure + VoiceChatView.onClickOffButton = { [weak self] in + //点击退出 + self?.destroyRoom() + } + ``` + +3. 被动退出。在加入房间之后订阅AUIRoomManagerRespDelegate的回调 + + ```swift + VoiceChatUIKit.shared.bindRespDelegate(delegate: self) + ``` + +#### 取消订阅 + +在退出房间时取消订阅 + +```swift +VoiceChatUIKit.shared.unbindRespDelegate(delegate: self) +``` + +#### 处理房间销毁 + +然后通过AUIRoomManagerRespDelegate回调方法中的onRoomDestroy来处理房间销毁 + +```swift +extension ViewController: AUIRoomManagerRespDelegate { + //房间销毁 + func onRoomDestroy(roomId: String) { + self.destroyRoom() + } + + func onRoomInfoChange(roomId: String, roomInfo: AUIKitCore.AUIRoomInfo) { + } + + func onRoomAnnouncementChange(roomId: String, announcement: String) { + } + + //被房主踢出 + func onRoomUserBeKicked(roomId: String, userId: String) { + self.destroyRoom() + } +} +``` diff --git a/markdown/chatroom/AUIVoiceRoom/uivoice_integration_ios.md b/markdown/chatroom/AUIVoiceRoom/uivoice_integration_ios.md index a1a86a4dafb..c8a52bc6b25 100644 --- a/markdown/chatroom/AUIVoiceRoom/uivoice_integration_ios.md +++ b/markdown/chatroom/AUIVoiceRoom/uivoice_integration_ios.md @@ -2,14 +2,14 @@ ## 示例项目 -声网提供 [AUIVoiceRoom](https://github.com/AgoraIO-Community/AUIVoiceRoom/tree/main) 示例项目供你参考。 +声网提供 [API-Examples-AUIKit/iOS/VoiceChatApp](https://github.com/AgoraIO-Community/API-Examples-AUIKit/tree/dev/ios/iOS/VoiceChatApp) 示例项目供你参考。 ## 准备开发环境 ### 前提条件 -- [Xcode](https://apps.apple.com/cn/app/xcode/id497799835?mt=12) 13.0 及以上。 +- [Xcode](https://apps.apple.com/cn/app/xcode/id497799835?mt=12) 14.0 及以上。 - iOS 设备,版本 13.0 及以上。 - 有效的苹果开发者账号。 - 可以访问互联网的计算机。确保你的网络环境没有部署防火墙,否则无法正常使用声网服务。 @@ -32,139 +32,65 @@ | key | type | value | | -------------------------------------- | ------ | ------------------------------------------------------------ | | Privacy - Microphone Usage Description | String | 使用麦克风的目的,例如 for a live interactive streaming | - | Privacy - Camera Usage Description | String | 使用摄像头的目的,例如 for a live interactive streaming | -
+### (可选)部署后端 -### 集成依赖 +为方便你快速集成语聊房,声网已经帮你部署好后端,无需你进行操作。 -本节介绍如何集成语聊项目所需的 AScenesKit 和 AUIKit 依赖: +声网在示例项目中提供的后端服务主机地址仅用于测试体验,请你不要商用。如需将项目商用,请参考[配置示例项目](//TODO)部署后端并在项目中配置后端服务主机地址。 -1. 开始前请确保你已安装 CocoaPods,如尚未安装 CocoaPods,参考 [Getting Started with CocoaPods](https://guides.cocoapods.org/using/getting-started.html#getting-started) 安装说明。 -2. 参考[克隆仓库](//TODO)在本地获取 `AUIVoiceRoom` 文件夹。 +### 集成依赖 -3. 将示例项目中如下文件复制到你的项目中: +本节介绍如何集成语聊项目所需的 AScenesKit 和 AUIKit 依赖: - - `AUIVoiceRoom/iOS/AUIKit` 文件夹 //TODO yf确认删除 - - `AUIVoiceRoom/AScenesKit` 文件夹 - - `AUIVoiceRoom/iOS/AUIVoiceRoom/AUIVoiceRoomKeyCenter.swift` +1. 开始前请确保你已安装 CocoaPods,如尚未安装 CocoaPods,参考 [Getting Started with CocoaPods](https://guides.cocoapods.org/using/getting-started.html#getting-started) 安装说明。 - 文件存放路径建议与示例项目中路径保持一致。 +2. 下载声网提供的 [AUIVoiceRoom/iOS/AScenesKit](https://github.com/AgoraIO-Community/AUIVoiceRoom/tree/dev/0.3.2/iOS/AScenesKit) 文件夹,并将该文件夹复制到与 `*.xcodeproj` 文件所在的同一级目录下。 -4. 在终端里进入你的项目根目录,并运行 `pod init` 命令。项目文件夹下会生成一个 `Podfile` 文本文件。 +3. 在终端里进入你的项目根目录,并运行 `pod init` 命令。项目文件夹下会生成一个 `Podfile` 文本文件。 -5. 打开 `Podfile` 文件,修改文件为如下内容。注意将 `Your App` 替换为你的 Target 名称。 +5. 打开 `Podfile` 文件,修改文件为如下内容。注意 target 和 path 的填写。 ```shell + source 'https://github.com/CocoaPods/Specs.git' platform :ios, '13.0' - target 'Your App' do - # path 与依赖库所在的实际路径一致即可 - pod 'AScenesKit', :path => './AScenesKit' - end - ``` - -6. 在终端内运行 pod install 命令安装依赖。成功安装后,Terminal 中会显示 Pod installation complete!。 - -### 部署后端 - -参考[配置示例项目](//TODO)进行部署。 - -## 实现语聊房 //TODO - -如下[时序图](#api-时序图)展示了如何登录即时通讯系统、获取房间列表、创建房间、进入房间、加入 RTC 频道、麦位管理、退出房间、离开 RTC 频道。声网云服务(Service)实现了房间列表的存储和房间生命周期的管理,声网即时通讯(IM)SDK 实现房间内的信令通信,声网 RTC SDK 承担实时音频的业务。本节会详细介绍如何调用声网云服务(`ChatRoomServiceProtocol`)、IM SDK API、RTC SDK API 完成这些逻辑。 - -
声网云服务为内部自研服务,暂不对外提供。你可以调用声网云服务的 API 用于测试,但是对于正式环境,声网建议你参考文档自行实现相似的一套服务。如需协助,请提交工单
- - -### 1. 初始化 VoiceRoomUIKit - -The initEngine function initializes the VoiceChatUIKit shared instance by setting up some basic configuration information. - -It first creates an AUICommonConfig object and sets the following properties: -host: The backend server host URL from KeyCenter.HostUrl -userId: The current user's ID from userInfo.userId -userName: The current user's name from userInfo.userName -userAvatar: The current user's avatar from userInfo.userAvatar -It then calls VoiceChatUIKit.shared.setup() and passes the AUICommonConfig along with nil for the rtcEngine and rtmClient since they will be created internally. + # target 需改为你的项目中实际的 Target 名称 + target 'AUIKitDemo' do + use_frameworks! -This configures the shared VoiceChatUIKit instance with the basic information it needs to interact with the backend services. The userId, userName, and userAvatar will be used to identify the local user. And the host specifies the server to connect to. - -So in summary, initEngine initializes VoiceChatUIKit with some basic app and user configuration before it can be used. - - -```swift - private func initEngine() { - //设置基础信息到VoiceChatUIKit里 - let commonConfig = AUICommonConfig() - commonConfig.host = KeyCenter.HostUrl - commonConfig.userId = userInfo.userId - commonConfig.userName = userInfo.userName - commonConfig.userAvatar = userInfo.userAvatar - VoiceChatUIKit.shared.setup(roomConfig: commonConfig, - rtcEngine: nil, - rtmClient: nil) - } -``` - -### 2. 获取房间列表 - -The getRoomInfoList method in onRefreshAction is used to fetch the initial page of room list data from the server when the user pulls to refresh. - -Some key points: - -It calls getRoomInfoList on VoiceChatUIKit to fetch room data from the server. - -It passes nil for lastCreateTime to indicate no filtering, and kListCountPerPage for pageSize to get the first page of results. - -In the callback, it reloads the roomList and collectionView with the new data. - -It adds a footer for pagination if the returned list is the full page size. - -So in summary, getRoomInfoList here retrieves the initial page of rooms to show when the user refreshes the list. - -```swift -VoiceChatUIKit.shared.getRoomInfoList(lastCreateTime: nil, pageSize: kListCountPerPage, callback: {[weak self] error, list in -}) -``` + # path 需为 AScenesKit 依赖库的实际路径 + pod 'AScenesKit', :path => './AScenesKit' + end -### 3. 创建房间 + post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + end + end + end + ``` -The createRoom method on VoiceChatUIKit is used to create a new voice chat room. +6. 进入根目录,在终端中运行如下命令安装与 AScenesKit 相关的 AUIKit 等依赖://TODO -It takes in an AUICreateRoomInfo object which contains details about the room to be created, like room name, number of seats etc. + ```shell + pod update --verbose + ``` -It also takes in a completion handler closure that will be called once the room is created successfully. This closure is passed a AUIRoomInfo object containing details about the newly created room. + 安装成功后,与 `*.xcodeproj` 文件所在的同一级目录下会出现一个 `*.xcworkspace` 文件。打开该文件即可体验安装了 AScenesKit 和 AUIKit 依赖的项目。 -The method calls the createRoom method on the roomManager property of VoiceChatUIKit, which seems to make the actual API call to create the room on the server. -Once the room is created successfully, the completion handler closure is called, passing the AUIRoomInfo object containing room details. This info is then used to instantiate a RoomViewController and display the new room's screen. +**常见问题排查**: -So in summary, the createRoom method on VoiceChatUIKit provides an easy way to create a new voice chat room from the client side and get back details of the created room. +如果在 Xcode 15 编译项目时遇到 `Sandbox: rsync.samba(47334) deny(1) file-write-create...` 报错信息,你可以在 Xcode 中选中 **PROJECT**,点击 **Build Settings**,在 Filter 搜索框中搜索 User Script Sandboxing,将该选项设为 **No**。//TODO Targets +## 实现语聊房 //TODO -```swift -let room = AUICreateRoomInfo() -room.roomName = "room name" -room.thumbnail = self.userInfo.userAvatar -room.micSeatCount = UInt(AUIRoomContext.shared.seatCount) -room.micSeatStyle = UInt(AUIRoomContext.shared.seatType.rawValue) -VoiceChatUIKit.shared.createRoom(roomInfo: room) { roomInfo in - let vc = RoomViewController() - vc.roomInfo = roomInfo - self.navigationController?.pushViewController(vc, animated: true) -} failure: { error in - // 错误提示 - ... -} -``` -### 4. 加载房间 //TODO -```swift -``` ## 下一步 diff --git a/markdown/chatroom/AUIVoiceRoom/uivoice_run_github_project_ios.md b/markdown/chatroom/AUIVoiceRoom/uivoice_run_github_project_ios.md index 7018c9374ae..d138cce1e64 100644 --- a/markdown/chatroom/AUIVoiceRoom/uivoice_run_github_project_ios.md +++ b/markdown/chatroom/AUIVoiceRoom/uivoice_run_github_project_ios.md @@ -6,7 +6,7 @@ ![](https://web-cdn.agora.io/docs-files/1697538180703) -架构解释: +架构图含义如下: - `AUIVoiceRoom`:代表语聊房 App。 - Controller:用于管理语聊 App 中房间列表页面和单个房间的详情页面。