# VOIP,唤醒未启动app、后台app ## 集成步骤 1. 拷贝demo里的nativeResources、Info.plist文件到项目根目录 2. (可选项)勾选manifest.json里的app模块配置Push(消息推送),如果勾选了Push模块,删除nativeResources/ios/UniApp.entitlements 3. nativeResources/ios/UniApp.entitlements文件里的aps-environment对应的值是development、production,一般开发阶段使用development,生产发布使用production,根据情况设置 4. ios打包的.mobileprovision需要包含消息推送功能 5. 集成插件,集成插件步骤请参考 [https://www.cnblogs.com/wenrisheng/p/18323027](https://www.cnblogs.com/wenrisheng/p/18323027) ## VOIP服务器配置 1. 登录苹果开发者系统生成VOIP证书(百度有很多资料) 2. 将cer证书和p12文件生成各自后端语言支持的证书,如: ### nodeJS语言服务器 服务器代码在demo/static/project-voip-server下 nodeJS语言需要cer和p12转成pem ``` cer转pem: openssl x509 -inform DER -in voip_services.cer -outform PEM -out cer.pem p12转pem: openssl pkcs12 -in voiptext.p12 -nodes -password pass:1234 -legacy -out key.pem ``` 将cer.pem、key.pem文件分别替换project-voip-server/customer_cer/mine下的文件 修改project-voip-server/src/app.controller.ts代码下的passphrase证书密码: ```typescript // 证书密码 const passphrase = '123456'; ``` 进入project-voip-server文件夹执行启动安装依赖和启动服务命令: ``` // 安装依赖 npm install // 启动服务 npm run start:dev ``` 浏览器或postman调用接口: token的值替换成app项目里获取到的token ``` http://127.0.0.1:3000/apn?token=xxxxxx ``` ### java语言服务器 依赖下面第三方,具体实现接口百度有很多,有需要可以咨询作者 java语言需要cer和p12转成一个p12 ``` com.turo pushy 0.13.10 ``` ## 接口 ```javascript import { UTSVoipMgr, UTSLocalNotification } from "@/uni_modules/wrs-uts-voip" ``` - 请求通知权限 ```javascript // 请求通知权限 UTSLocalNotification.requestAuthorization({ types: ["badge", "sound", "alert"] }, (resp) => { let flag = resp.flag if (!flag) { // 请求权限失败 console.log("requestAuthorization:" + JSON.stringify(resp)) } }) ``` - 设置VOIP回调 ```javascript // 流程: // 1. app把token上传给后端 // 2. 后端调用苹果的apn接口发送数据给苹果服务器 // 3. 苹果服务器会把消息转发给手机 // 4. 手机app收到后,先回调didReceiveIncomingPush接口 // 5. 如果消息体里的数据符合插件里定义的voip数据(消息体参考文档),则会自动拉起接听电话界面 // 6. 用户接听或拒绝电话 UTSVoipMgr.onCallback((resp) => { let opt = resp.opt switch (opt) { // 获取到本机token,需要上传给后端,后端发送voip时需要token参数,token可以理解为手机的ID case "didUpdatePushCredentials": let token = resp.token console.log("token:" + token) break; // 收到后端发送的数据 case "didReceiveIncomingPush": console.log("didReceiveIncomingPush:" + JSON.stringify(resp)) break; // 拉起接听电话界面结果 case "startCall": getApp().globalData.uuid = resp.uuid console.log("startCall:" + JSON.stringify(resp)) break; // 用户接听了电话 case "performAnswerCall": console.log("performAnswerCall:" + JSON.stringify(resp)) break; // 电话挂断 case "performEndCall": console.log("performEndCall:" + JSON.stringify(resp)) break; default: console.log(JSON.stringify(resp)) break; } }) ``` 后端接口发起voip参数如下: ``` const payload = { business: { type: 0, // 0: 自动拉起电话接听界面 params: { // 参数 hasVideo: true, localizedCallerName: "张三来电", timeout: 5,// 可选参数,单位秒,传了timeout参数,无论用户有没有接听电话,定时器到了都会挂断电话,如果想取消定时器请调用deleteWaitingResponseUuid接口取消定时器 remoteHandle: { type: 1, // 1: generic 2:phoneNumber 3: emailAddress value: "18820406059" } } } }; ``` - 设置通知回调 ```javascript // 设置通知回调 UTSLocalNotification.onCallback((resp) => { let opt = resp.opt switch (opt) { // 将要显示通知 case "willPresent": break; // 用户点击打开通知 case "didReceive": console.log("用户点击打开通知:" + JSON.stringify(resp)) break; default: break; } }) ``` - 初始化本地通知 ``` UTSLocalNotification.notificationInit() ``` - 发送本地通知 ```javascript // 发送本地通知 UTSLocalNotification.add({ title: "张三来电", subtitle: "VOIP", body: "您收到了一条新消息", sound: "default", trigger: { timeInterval: 0.2, repeats: false }, identifier: "123456" }, (notResp)=>{ }) ``` - 挂断电话 ```javascript UTSVoipMgr.endCall({ uuid: getApp().globalData.uuid }, (resp)=>{ console.log(JSON.stringify(resp)) }) ``` - 取消自动挂断电话 ``` UTSVoipMgr.deleteWaitingResponseUuid({ uuid: "xxx" }) ``` - 获取app运行状态,仅支持iOS ``` let state = UTSVoipMgr.getApplicationState() switch (state) { // active case 0: break; // unactive case 1: break; // background case 2: break; default: break; } ``` - 设置桌面icon角标 ```javascript let badge = 0 UTSLocalNotification.setBadgeNum(badge, (resp)=>{ console.log(JSON.stringify(resp)) }) ```