另外,在实现demo之前你需要一些准备工作,可参见【开发环境】。
项目名为:VoiceChatDemo,打开终端,进入根目录VoiceChatDemo下,输入命令podinit,该命令生成Podfile文件,并在Podfile文件中,输入pod'AgoraRtcEngine_iOS','4.1.1’,表示集成声网sdk。之后在终端中输入命令podinstall,表示下载依赖。
本次实现的语聊房Demo,所以只需要给予麦克风权限
本次语音聊天室Demo主要涉及两个页面,一是用户加房页面ViewController,二是用户聊天室页面RoomController。而在RoomController中包含一个UICollectionView,用于展示远端用户视图。
importUIKitclassViewController:UIViewController{@IBOutletweakvarappidTF:UITextField!@IBOutletweakvartokenTF:UITextField!@IBOutletweakvaruidTF:UITextField!@IBOutletweakvarroomTF:UITextField!overridefuncviewDidLoad(){super.viewDidLoad()//Doanyadditionalsetupafterloadingtheview.}}加房跳转逻辑在页面中设计,具体如下图
当用户点击加入房间button时,会自动跳转到用户聊天室页面,这种方式称为Segue,表示从一种场景转换到另外一种场景中。
在RoomController.swift文件中,实现聊天室逻辑功能
2.1初始化操作
1)导入AgoraSDK
importAgoraRtcKit//自3.0.0版本起,AgoraRtcEngineKit类名更换为AgoraRtcKit2)初始化声网引擎
//初始化AgoraRtcEngineKit,可加入自定义配置,比如加入频道是否开启麦克风、摄像头等。letconfig=AgoraRtcEngineConfig()config.appId=appidconfig.channelProfile=profileagoraKit=AgoraRtcEngineKit.sharedEngine(with:config,delegate:self)agoraKit.enableAudio()agoraKit.disableVideo()agoraKit.enableAudioVolumeIndication(200,smooth:3,reportVad:true)//默认加入频道即发送音频,不发送视频letoption=AgoraRtcChannelMediaOptions()option.publishCameraTrack=falseoption.publishMicrophoneTrack=trueoption.enableAudioRecordingOrPlayout=trueoption.clientRoleType=.broadcasteroption.autoSubscribeAudio=true2.2聊天室页面设计
1)定义UserList
如下图,定义一个CollectionView来渲染远端用户,名为UserList,当远端用户加房时,UICollectionView中就会增加一个自定义的Cell。
自定义的Cell的nib文件需要和RoomCell关联。
在使用Cell前,需要注册自定义的Cell到UICollectionView中。
varnibName=UINib(nibName:"RoomCell",bundle:nil)userList.register(nibName,forCellWithReuseIdentifier:"RoomCell")2)数据绑定
那么,怎么把自定义的Cell显示在CollectionView里面,也就是说当远端用户加房时是怎么显示在页面上的?
userList.delegate=selfuserList.dataSource=self那么dataSource是怎么绑定数据的呢?当远端用户加房后,怎么显示在界面上?
数据源是userArray,userArray是远端用户的列表,当远端用户加入房间时会传入参数uid,并将uid存到userArray数组中,当远端离开房间时,会调用remove()方法,将用户uid移除,在此过程中,控件需要重新刷新用户列表,即`userList.reloadData()``,将用户视图实时更新。
//远端用户加入房间funcrtcEngine(_engine:AgoraRtcEngineKit,didJoinedOfUiduid:UInt,elapsed:Int){letlength=userArray.countiflength==0{userArray.insert(Int(uid),at:0)}else{userArray.insert(Int(uid),at:length-1)}userList.reloadData()}//远端用户离开房间funcrtcEngine(_engine:AgoraRtcEngineKit,didOfflineOfUiduid:UInt,reason:AgoraUserOfflineReason){varindexNum:Int=0for(index,value)inuserArray.enumerated(){ifvalue==uid{indexNum=index}}userArray.remove(at:indexNum)userList.reloadData()}另外,当用户加入房间后,用户的uid是怎么显示在界面上的呢?numberOfItemsInSection表示区域内有多少个item(元素),也就是表示数组的个数,如果数组为5,那么就会返回5给collectionView;每一个cell都可自己定义,有几个元素,那么第二个方法就会调用几次。而当用户进来时,显示用户uid,即cell.uidLabel.text="(userArray[indexPath.row])"
extensionRoomController:UICollectionViewDataSource{funccollectionView(_collectionView:UICollectionView,numberOfItemsInSectionsection:Int)->Int{returnuserArray.count}funccollectionView(_collectionView:UICollectionView,cellForItemAtindexPath:IndexPath)->UICollectionViewCell{letcell=collectionView.dequeueReusableCell(withReuseIdentifier:"RoomCell",for:indexPath)as!RoomCellcell.uidLabel.text="\(userArray[indexPath.row])"returncell}3)mute/unmute实现
当用户点击开启麦克风按钮时,会调用muteLocalAudioStream(false)方法,当点击关闭麦克风时,参数时true。
//打开麦克风@IBActionfuncopenMic(_sender:UIButton){agoraKit.muteLocalAudioStream(false)}//关闭麦克风@IBActionfunccloseMic(_sender:UIButton){agoraKit.muteLocalAudioStream(true)}