客户端实现
本文介绍如何使用声网灵隼全功能版本的客户端示例项目在 iOS 客户端实现设备管理、呼叫、通话、告警等功能。
全功能版本的客户端示例项目 提供用户注册/登录、绑定/解绑设备、Wi-Fi 二维码配网、呼叫、实时音视频等功能。
如果你没有自研的设备管理等模块,声网建议你使用全功能版本示例项目。
前提条件
开始前,请确保你的开发环境满足以下条件:
- Xcode(推荐最新版本)。
- iOS 12.0 或以上版本的 Apple 设备。
- 参考开通并配置声网灵隼物联网服务开通灵隼服务
跑通示例项目
-
从 GitHub 上下载最新版本的 iOS 客户端示例项目。
-
在项目的
ag-iot-ios-app\AgoraIoT
目录运行pod install
安装依赖。 -
连接上 iOS 设备后,点击
.xcworkspace
文件打开项目,并在 iOS Device 选项中勾选上你的 iOS 设备。 -
使用 Xcode 打开项目。修改配置文件
Config.swift
,将以下配置项修改为你在灵隼控制台的应用配置>>开发者选项页面中获取的相关参数。详见开通并配置声网灵隼服务。Swift// 声网灵隼控制台的应用配置>>开发者选项中的 App ID
public static let appId = "4b31f**********************3037" //appid
// 声网灵隼控制台的应用配置>>开发者选项中的 Project ID
public static let projectId:String = "a******_C" // 项目id"
// Easemob App Key。在开通声网灵隼服务之后,可以在应用配置页面中的开发者选项选项卡中获取
public static let ntfAppKey: String = "52****88#3****2" //离线推送的appkey
// APNS 证书名。在开通声网灵隼服务之后,可以在应用配置页面中的开发者选项选项卡中获取
public static let ntfApnsCertName:String = "xxx.xxx.xxx"//离线推送的AnpsCertName
// 声网灵隼控制台的应用配置>>开发者选项中的 Master Server URL
public static let masterServerUrl:String = "https://un2nfllop5.execute-api.cn-north-1.amazonaws.com.cn/Prod"
// 声网灵隼控制台的应用配置>>开发者选项中的 Slave Server URL
public static let slaveServerUrl:String = "https://api.sd-rtn.com/agoralink/cn/api" -
在项目 TARGETS 下的 Signing & Capabilities 界面勾选 Automatically manage signing,配置你的苹果开发者账号和 Bundle Identifier。
-
连接上 Apple 设备后,编译并运行项目。
-
在登录页面选择注册新账户或者登录已有账户,目前国内只支持手机号注册。
-
在登录成功后的页面,可以点击 + 号添加新设备(设备产品码请参考参考开通灵隼服务文档获取产品二维码章节),或者选择已经添加设备实时预览对应设备的画面(设备端示例项目请参考实现设备端功能文档)。
客户端实现
iOS 客户端的核心逻辑如下。
初始化
参考以下步骤调用 initialize
方法进行初始化。
let param:InitParam = InitParam()
// 声网 App ID。在开通声网灵隼服务之后,可以在应用配置页面中的开发者选项选项卡中获取。
param.rtcAppId = Config.appId
param.logFilePath = FileCenter.logFilePath()
param.subscribeVideo = true
param.subscribeAudio = true
param.publishVideo = false
param.publishAudio = false
// APNS 证书名。在开通声网灵隼服务之后,可以在应用配置页面中的开发者选项选项卡中获取。
param.ntfApnsCertName = Config.ntfApnsCertName
// APNS 证书秘钥。在开通声网灵隼服务之后,可以在应用配置页面中的开发者选项选项卡中获取。
param.ntfAppKey = Config.ntfAppKey
// 开发者选项>>呼叫服务>>Master Server URL 获取
param.masterServerUrl = "http://iot-api-gateway.sh.agoralab.co/api"
// 开发者选项>>呼叫服务>>Slave Server URL 获取
param.slaveServerUrl = "https://un2nfllop5.execute-api.cn-north-1.amazonaws.com.cn/Prod"
// 开发者选项>>呼叫服务>>Project ID 获取
param.projectId = "Your Project ID"
let ret = AgoraIotSdk.iotsdk.initialize(initParam: param, netStatus: {status,msg in}, callBackFilter: { ec, msg in return (ec,msg)})
注册用户账号
可以通过邮箱和手机号码两种方式来注册用户账号。账号注册分为两个步骤:
-
通过手机号码或者邮箱账号获取注册验证码。
Swift//
// 获取验证码,这里 使用getCode来获取邮箱验证码,getSms来获取手机验证码,type固定为""REGISTER""
// 获取手机验证码时,lang表示所在国家语言
// 相应的验证码,过几分钟后会发送到手机短信或者邮箱邮件
// 接口通过 result 异步返回
AgoraIotSdk.iotsdk.accountMgr.getCode(email: email, type: "REGISTER", result: {errCode,errMsg in})
AgoraIotSdk.iotsdk.accountMgr.getSms(phone: phone, type: "REGISTER",lang:"ZH_CN", result: {errCode,errMsg in}) -
使用手机号或邮箱、验证码和密码进行账号注册。
accountName
可以填入手机号码或者邮箱作为账户名,你也可以使用其他账户名。Swiftif(registerWithPhoneNumber){
//使用手机注册
AgoraIotSdk.iotsdk.accountMgr.register(account: acc, password: pwd,code:code,email: nil,phone:phone, result: result: {errCode, errMsg in})
}
else{
//使用邮箱注册
AgoraIotSdk.iotsdk.accountMgr.register(account: acc, password: pwd,code:code,email: email,phone:nil, result: result: {errCode, errMsg in})
}
登录用户账号
参考以下步骤登录用户账号:
//
// 使用(账号名+密码)方式进行登录
// 登录成功/失败后,触发 result 回调登录结果
//
AgoraIotSdk.iotsdk.accountMgr.login(account: acc, password: pwd,result: {errCode, errMsg in})
当用户账号成功登录后,可以开始进行正式的操作,包括设备管理、告警信息查询、系统信息查询、用户信息更新等。
添加设备
当前版本中,只支持设备端扫描二维码进行添加,需要客户端生成二维码:
1、生成设备二维码图。在客户端需要使用 JSON 字符串生成相应的二维码图,其中 JSON 字符串格式为:
{
"s": "wifi_ssid",
"p": "wifi_password",
"u": "code_user_id",
"k": "productkey"
}
其中:
wifi_ssid
: 配置给设备的 WIFI SSID。wifi_password
: 配置给设备的 WIFI 网络访问密码。code_user_id
: 用于配置的特定用户 ID,可以通过AgoraIotSdk.iotsdk.accountMgr.getUserId()
获取。product_key
: 配置的产品 ID。获取方式详见开通声网灵隼服务。
JSON 内容示例:
{
"s":"TP-LINK_AGORA08",
"p":"Agora123456",
"u":"690191659910586368",
"k":"EJImm64m65ECOl5"
}
然后使用二维码生成库(例如 CoreImage.CIFilterBuiltins
),根据 JSON 内容生成二维码 Bitmap,并提供给设备端摄像头来扫描。具体生成方式可以参考 SDK 自带的示例项目中的 /View/Home/SetDevice/SDStep3View.swift
文件。
-
设备摄像头扫描二维码图进行主动绑定。
-
绑定设备列表查询。你可以通过设备列表查询方法来获取当前所有绑定设备列表。
Swift// 查询当前账号下绑定设备列表,通过回调 result 方法返回设备列表
AgoraIotSdk.iotsdk.deviceMgr.queryAllDevices(result: {errCode,errMsg,devs in}) -
设备改名。设备绑定成功后,会使用默认的设备名。用户也可以根据需要,将设备名更改成方便记忆的名字。
Swift// 设备进行改名操作,通过 result 方法返回改名是否成功
AgoraIotSdk.iotsdk.deviceMgr.renameDevice(device: dev, newName: newName, result: {errCode,errMsg in})
客户端呼叫设备端
-
客户端发出呼叫请求。
Swift// 呼叫设备端,可以同时附带一些呼叫消息
AgoraIotSdk.iotsdk.callkitMgr.callDial(device:dev,attachMsg: "",result:{
(ec,msg) in
cb(ec == ErrCode.XOK ? true : false , msg)
},peerAction: {s in
log.i("peer \(s)")
}) -
客户端发出呼叫请求成功后,设备端会有三种状态回应:
- 如果设备端正常接听,
peerAction
返回.Answer
,开始音视频通话。 - 如果设备端拒绝接听,
peerAction
返回.Hangup
,结束本次通话。 - 如果设备端接听超时,
peerAction
返回.Timeout
,结束本次通话。
- 如果设备端正常接听,
-
正常通话过程中,客户端可以发送音视频,对端也发送音视频。当设备接听后挂断电话,
peerAction
返回.Hangup
。 -
如果客户端想要结束通话,调用
AgoraIotSdk.iotsdk.callkitMgr.callHangup()
方法主动挂断电话。SwiftAgoraIotSdk.iotsdk.callkitMgr.callHangup(result: {errCode,errMsg in})
设备端呼叫客户端
-
接收到来电呼叫事件需要在初始化完成后注册来电回调接口
SwiftAgoraIotSdk.iotsdk.callkitMgr.register(incoming: {peerId,msg,action in})
-
客户端处于空闲状态时,如果有设备端呼叫,会接收到来电呼叫事件
AgoraIotSdk.iotsdk.ICallkitMgrCallback.onPeerIncoming
,你可以根据自己的业务逻辑显示来电界面。 -
客户端根据实际的业务逻辑进行处理。
- 如果客户端拒绝,则调用
AgoraIotSdk.iotsdk.callkitMgr.callHangup()
方法挂断 ,结束本次通话。 - 如果客户端接听,则调用
AgoraIotSdk.iotsdk.callkitMgr.callAnswer()
方法,进入双方通话状态。客户端可以使用AgoraIotSdk.iotsdk.callkitMgr.callHangup()
主动挂断通话。如果设备端挂断通话,客户端会收到AgoraIotSdk.iotsdk.ICallkitMgrCallback.onPeerHangup()
回调。
- 如果客户端拒绝,则调用
告警信息查询
当有人员经过监控设备时,设备端会将 入侵检测、移动侦测相应的事件上报给服务器。
客户端可以通过相应的接口进行查询,设置不同的查询参数字段,可以进行相应的过滤。
IAlarmMgr.QueryParam queryParam = new IAlarmMgr.QueryParam();
queryParam.mPageIndex = 1;
queryParam.mPageSize = 512;
queryParam.mMsgType = -1;
queryParam.mMsgStatus = -1;
int ret = AIotAppSdkFactory.getInstance().getAlarmMgr().queryByPage(queryParam);
系统告警查询
设备的绑定、解绑、上线、下线等系统事件,也会同步上报给服务器。
客户端可以通过相应的接口进行查询,设置不同的查询参数字段,可以进行相应的查询过滤。
var query = IAlarmMgr.QueryParam(dateBegin: nil)
query.status = status
query.messageType = type
query.createdDateBegin = nil
query.createdDateEnd = date
query.pageSize = 10
query.currentPage = 1
AgoraIotSdk.iotsdk.alarmMgr.queryByParam(queryParam: query, result: {errCode,errMsg,alarms in})
发送和接收云信令 RTM 消息
你可以通过 sendMessage
和 messageReceived
发送和接收云信令 RTM 消息。
// 连接 RTM 云信令
AgoraIotLink.iotsdk.deviceMgr.sendMessageBegin(device: device!) { ec, msg in
log.level(ec == ErrCode.XOK ? .info : .error, "demo sendMessageBegin() \(msg)(\(ec))")
if(ec != ErrCode.XOK){
AGToolHUD.showFaild(info: msg)
}
} statusUpdated: { status,msg,data in
if(status == .DataArrived){
log.i("demo sendMessage status updated:\(status),\(msg)")
AGToolHUD.showSuccess(info: "rtm info :\(msg)")
}
else if(data != nil){
log.i("demo 收到设备数据长度:" + String(data!.count))
AGToolHUD.showSuccess(info: "rtm info :\(msg)")
}
}
// 发送 RTM 云信令消息
AgoraIotLink.iotsdk.deviceMgr.sendMessage(data: data, description: "this is description") { ec, msg in
log.i("demo send message \(msg)(\(ec))")
if(ec != ErrCode.XOK){
AGToolHUD.showFaild(info: msg)
}
}
// 与 RTM 云信令断开连接
AgoraIotLink.iotsdk.deviceMgr.sendMessageEnd()
登出用户账号
你可以通过以下方法登出用户账号。
AgoraIotSdk.iotsdk.accountMgr.logout(result: {errCode,errMsg in})
注销用户账号
你可以通过以下方法注销用户账号。
AgoraIotSdk.iotsdk.accountMgr.unregister(result: {errCode,errMsg in})