当前位置: 首页 > news >正文

iOS开发-NotificationServiceExtension实现实时音视频呼叫通知响铃与震动

iOS开发-NotificationServiceExtension实现实时音视频呼叫通知响铃与震动

在之前的开发中,遇到了实时音视频呼叫通知,当App未打开或者App在后台时候,需要通知到用户,用户点击通知栏后是否接入实时音视频的视频或者音频通话。

在iOS需要为工程新建Target:NotificationServiceExtension

一、主工程配置

需要在主工程中开启推送功能,配置证书。

在这里插入图片描述

二、新建NotificationServiceExtension的target

新建NotificationServiceExtension的target

在这里插入图片描述

三、实现NotificationService

在NotificationService的方法

// 主要代码
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler- (void)serviceExtensionTimeWillExpire;

在didReceiveNotificationRequest实现呼叫响铃及震动效果。

// 通过通知的Sound设置为voip_call.caf,这里播放一段空白音频,音频结束后结束震动NSString *path = [[NSBundle mainBundle] pathForResource:@"blank_call.mp3" ofType:nil];AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &soundID);AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, soundCompleteCallback, NULL);

完整代码如下

#import "NotificationService.h"
#import <AVFoundation/AVFAudio.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>@interface NotificationService ()
{SystemSoundID soundID;
}@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;@property (nonatomic, strong) NSMutableArray *requests;@end@implementation NotificationService- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {self.contentHandler = contentHandler;self.bestAttemptContent = [request.content mutableCopy];BOOL playVoice = NO;NSString *chatPushVo = [self.bestAttemptContent.userInfo objectForKey:@"chatPushVo"];if (chatPushVo && [chatPushVo isKindOfClass:[NSString class]] && chatPushVo > 0) {NSDictionary *dict = [self dictionaryWithJsonString:chatPushVo];if (dict && [dict isKindOfClass:[NSDictionary class]]) {NSString *type = [NSString stringWithFormat:@"%@", [dict objectForKey:@"type"]];// type : 0 呼叫if ([@"0" isEqualToString:type]) {playVoice = YES;// 通过通知的Sound设置为voip_call.caf,这里播放一段空白音频,音频结束后结束震动NSString *path = [[NSBundle mainBundle] pathForResource:@"blank_call.mp3" ofType:nil];AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &soundID);AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, soundCompleteCallback, NULL);[self playVoiceWithContent:self.bestAttemptContent.userInfo];}}}if (playVoice == NO) {self.contentHandler(self.bestAttemptContent);}
}- (void)playVoiceWithContent:(NSDictionary *)userInfo {//  iOS 10之前前台没有通知栏// 此处调用之前的语音播报的内容[self playRegisterNotifications:userInfo];
}- (void)playRegisterNotifications:(NSDictionary *)userInfo {[self registerNotifications:userInfo];
}- (void)registerNotifications:(NSDictionary *)userInfo {[self startShakeSound];
}/// 开始响铃
- (void)startShakeSound {// 声音AudioServicesPlaySystemSound(soundID);// 震动AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);self.contentHandler(self.bestAttemptContent);
}/// 结束响铃
- (void)stopShakeSound {AudioServicesDisposeSystemSoundID(soundID);AudioServicesRemoveSystemSoundCompletion(soundID);
}//AudioServicesAddSystemSoundCompletion的回调函数
void soundCompleteCallback(SystemSoundID sound,void * clientData) {if (sound == kSystemSoundID_Vibrate) {AudioServicesPlayAlertSound(sound);//重复响铃震动} else {// 移除AudioServicesDisposeSystemSoundID(sound);AudioServicesRemoveSystemSoundCompletion(sound);AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);}
}- (void)serviceExtensionTimeWillExpire {// Called just before the extension will be terminated by the system.// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.self.contentHandler(self.bestAttemptContent);
}/**json转成NSDictionary@param jsonString json字符串@return NSDictionary*/
- (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {if (jsonString == nil) {return nil;}NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];NSError *err;NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];if(err) {return nil;}return dic;
}@end

四、使用推送

我这里使用的极光推送,注意需要设置推送的mutable-content=1字段。

在这里插入图片描述

五、点击通知后处理是否通实时音视频视频通话

在收到通知后,用户点击点击通知后处理是否通实时音视频视频通话逻辑。

在AppDelegate的方法

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

增加didReceiveRemoteNotification

// 获取启动时收到的APNNSDictionary *userInfo = [[DFPushManager shareInstance] launchOptionsRemoteNotification:launchOptions];if (userInfo) {[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {}];}

当收到通知后,在didReceiveRemoteNotification中处理是否接通实时音视频的视频通话的逻辑

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {DFDebugLogger(@"didReceiveRemoteNotification");[[SDPushManager shareInstance] handleRemoteNotification:application userInfo:userInfo completion:nil];NSLog(@"收到通知:%@", userInfo);[[SDPushManager shareInstance] setBadgeNumberMax:nil];if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {// 登录后调用check__weak typeof(self) weakSelf = self;if (userInfo && [userInfo isKindOfClass:[NSDictionary class]]) {NSString *chatPushVo = [userInfo objectForKey:@"chatPushVo"];if (chatPushVo && [chatPushVo isKindOfClass:[NSString class]] && appPushVo.length > 0) {NSDictionary *dict = [DFJsonUtil dictionaryWithJsonString: chatPushVo];if (dict && [dict isKindOfClass:[NSDictionary class]]) {NSString *type = [NSString stringWithFormat:@"%@", [dict objectForKey:@"type"]];// type : 0 呼叫/// 0/用户呼叫// 打开接听页面,进行接听}}}}completionHandler(UIBackgroundFetchResultNewData);
}

六、小结

iOS开发-NotificationServiceExtension实现实时音视频呼叫通知与语音播报

在之前的开发中,遇到了实时音视频呼叫通知,当App未打开或者App在后台时候,需要通知到用户,用户点击通知栏后是否接入实时音视频的视频或者音频通话。

学习记录,每天不停进步。

相关文章:

iOS开发-NotificationServiceExtension实现实时音视频呼叫通知响铃与震动

iOS开发-NotificationServiceExtension实现实时音视频呼叫通知响铃与震动 在之前的开发中&#xff0c;遇到了实时音视频呼叫通知&#xff0c;当App未打开或者App在后台时候&#xff0c;需要通知到用户&#xff0c;用户点击通知栏后是否接入实时音视频的视频或者音频通话。 在…...

性能调试【学习笔记】

什么是调优&#xff1f; 每执行一个Java命令&#xff0c;就分配一个JVM&#xff0c;调优时不要混淆。 根据需求进行JVM规划和预调优优化运行JVM的运行环境&#xff08;慢、卡顿&#xff09;解决JVM运行过程中出现的各种问题&#xff08;内存泄露、内存溢出OOM&#xff09; 生…...

【taro react】---- 获取元素的位置和宽高等信息

1. 需求分析 添加节点的布局位置的查询请求。相对于显示区域&#xff0c;以像素为单位。其功能类似于 DOM 的 getBoundingClientRect。返回 NodesRef 对应的 SelectorQuery。区分小程序和H5的环境&#xff0c;调用 getBoundingClientRect 获取对应的信息。 2. H5 实现 判断传…...

Java【Spring】项目创建、存储和获取 Bean 的基本方式

文章目录 前言一、创建 Spring 项目1, 创建 Maven 项目2, 添加 Spring 依赖3, 创建启动类 二、存储 Bean 的基本方式1, 创建 Bean2, 存储 Bean 三、获取 Bean 的基本方式1, 获取上下文对象2, 获取 Bean3, 使用 Bean 总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的…...

docker minio安装

1.介绍 Minio是一款开源的对象存储服务&#xff0c;它可以在任何硬件或云平台上提供高性能、高可用性和高安全性的存储解决方案。Minio最新版是2021年11月发布的RELEASE.2021-11-24T23-19-33Z&#xff0c;它带来了以下几个方面的改进和新特性&#xff1a; - 支持S3 Select AP…...

设计模式-命令模式在Java中的使用示例-桌面程序自定义功能键

场景 欲开发一个桌面版应用程序&#xff0c;该应用程序为用户提供了一系列自定义功能键&#xff0c;用户可以通过这些功能键来实现一些快捷操作。 用户可以将功能键和相应功能绑定在一起&#xff0c;还可以根据需要来修改功能键的设置&#xff0c;而且系统在未来可能还会增加…...

分冶算法 剑指 07 重建二叉树 排序算法:剑指45 把数组排成最小的数 10-I 斐波那契数列

来记录几个注意事项 1.vector容器里利用find&#xff08;&#xff09;函数 不同于map&#xff08;map有find方法&#xff09;&#xff0c;vector本身是没有find这一方法&#xff0c;其find是依靠algorithm来实现的。 所以要包含头文件 #include <iostream> #include <…...

Postgresql取消正在执行的任务或强制终止正在执行的任务

Postgresql取消正在执行的任务或强制终止正在执行的任务 要停止 PostgreSQL 数据库中当前正在执行的所有任务&#xff0c;可以使用以下方法&#xff1a; 使用 pg_cancel_backend 函数&#xff1a;连接到 PostgreSQL 数据库&#xff0c;并执行以下命令以停止所有正在执行的任务…...

【Linux】Centos7 的 Systemctl 与 创建系统服务 (shell脚本)

Systemctl systemctl 命令 # 启动 systemctl start NAME.service # 停止 systemctl stop NAME.service # 重启 systemctl restart NAME.service # 查看状态 systemctl status NAME.service # 查看所有激活系统服务 systemctl list-units -t service # 查看所有系统服务 syste…...

Redis集群Cluster搭建

Redis集群Cluster搭建 集群框架1、下载redis2.创建Cluster文件3.修改redis配置文件4.启动redis5.链接各个redis6.分配槽位7.添加从机节点&#xff08;备份Redis&#xff09;8.以集群方式登录9.使用开源Redis可视化客户端链接 集群框架 三个集群节点&#xff0c;每个节点有个副本…...

swing组件应用

1. 组件概述 &#xff08;1&#xff09; 说明 组件组成Java 的图形界面的各个元素&#xff0c;按照不同的功能&#xff0c;可分为 顶层容器、中间容器、基本组件。顶层容器为java.awt.Window的子类&#xff0c;有JFrame、JDialog等。中间容器和基础组件都为javax.swing.JCompo…...

Spring学习记录----十五、面向切面编程AOP+十六、Spring对事务的支持

十五、面向切面编程AOP IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能&#xff0c;把它转化成组件。 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;面向方面编程。&#xff08;AOP是一种编程技术&#xff09; …...

Color Correction (颜色校正)

介绍 在Unity中&#xff0c;Color Correction (颜色校正) 是一种用于调整场景或游戏画面颜色的技术。其中&#xff0c;Curves&#xff08;曲线&#xff09;和Saturation&#xff08;饱和度&#xff09;是常用的Color Correction工具。通过Curves&#xff0c;可以对RGB通道进行…...

Unity-缓存池

一、.基础缓存池实现 继承的Singleton脚本为 public class Singleton<T> where T : new() {private static T _instance;public static T GetIstance(){if (_instance null)_instance new T();return _instance;} } 1.PoolManager using System.Collections; using S…...

ubuntu samba 配置常见问题

samba配置&#xff1a; sudo vi /etc/samba/smb.conf [xxx 共享文件名] comment share folder browseable yes writable yes guest ok yes path /workdir/code/favarite create mask 0777 directory mask 0777 sudo /etc/init.d/smbd restart 重启smb服务 以上操作…...

vue3.3-TinyMCE:TinyMCE富文本编辑器基础使用

一、TinyMCE官网 GitHub - tinymce/tinymce TinyMCE中文文档中文手册 二、官网介绍 TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器。同类程序有&#xff1a;UEditor、Kindeditor、Simditor、CKEditor、wangEditor、Suneditor、froala等等。 TinyMCE的优势&…...

基于以太坊+IPFS的去中心化数据交易方法及平台

自己的论文&#xff0c;哎费事 目录 基于以太坊IPFS的去中心化数据交易方法及平台 基于以太坊IPFS的去中心化数据交易方法及平台 摘要&#xff1a; 数据交易过程中存在数据权属不明和数据安全问题。本文开发了一种基于以太坊IPFS的去中心化数据交易方法及平台。方法包括&am…...

NestJS 的 拦截器 学习

拦截器会用到RxJs&#xff0c;所以在学习拦截器之前可以先了解一下它。 拦截器是使用Injectable()装饰器装饰的类并且实现了接口NestInterceptor。 拦截器受到 AOP(面向切面编程)技术的启发&#xff0c;具有如下的功能&#xff1a; 在方法执行之前/之后绑定额外的逻辑转换函…...

Spring AOP 中的代理对象是怎么创建出来的?

文章目录 1. AOP 用法2. 原理分析2.1 doCreateBean2.2 postProcessAfterInitialization2.3 getAdvicesAndAdvisorsForBean2.3.1 findCandidateAdvisors2.3.2 findAdvisorsThatCanApply2.3.3 extendAdvisors 2.4 createProxy 今天和小伙伴们聊一聊 Spring AOP 中的代理对象是怎么…...

解决@Scope(“prototype“)不生效的问题

目录 Scope(“prototype“)不生效Scope(“prototype“)正确用法——解决Bean多例问题 1.问题&#xff0c;Spring管理的某个Bean需要使用多例2.问题升级3. Spring给出的解决问题的办法&#xff08;解决Bean链中某个Bean需要多例的问题&#xff09; Scope(“prototype“)不生效 …...

Mybatis 知识点

Mybatis 知识点 1.1 Mybatis 简介 1.1.1 什么是 Mybatis Mybatis 是一款优秀的持久层框架支持定制化 SQL、存储过程及高级映射Mybatis 几乎避免了所有的 JDBC 代码和手动设置参数以及获取结果集MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO…...

PHP中关于is,between,in等运算符的用法是什么?

我们学习了解了这么多关于PHP的知识&#xff0c;不知道你们对PHP中关于is&#xff0c;between&#xff0c;in等运算符的用法是什么&#xff1f;是否已经完全掌握了呢&#xff0c;如果没有&#xff0c;那就跟随本篇文章一起继续学习吧 相关推荐&#xff1a;关于PHP中的增删改如…...

2023-07-29:华清远见嵌入式2017年线下班:文件IO笔记

这里写目录标题 华清远见嵌入式2017年线下班&#xff1a;文件IO笔记文件权限文件IO文件创建和打开操作文件关闭操作出错处理创建设备文件 || create || 老师自己忘了文件读操作练习&#xff1a;计算文件的大小&#xff1f;文件写操作练习&#xff1a;打开file1和file2&#xff…...

2023年第四届“华数杯”数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&#xff0…...

Typescript第七章 处理错误(返回null,抛出异常,返回异常,Option类型)

第七章 处理错误 Typescript竭尽所能&#xff0c;把运行时异常转移到编译时。Typescript是功能丰富的系统&#xff0c;加上强大的静态和符号分析能力&#xff0c;包揽了大量辛苦的工作。 但是有些问题是无法避免的&#xff0c;比如网络和文件系统异常&#xff0c;解析用户输入…...

Qt库xcb问题

首先在~/.bashrc中加入 export QT_DEBUG_PLUGINS1然后看具体的报错 查看某个库链接的库&#xff1a; ldd libqxcb.so然后找到真正缺少的库&#xff0c;再在路径下搜索&#xff0c;然后建立软链接。 https://blog.csdn.net/LOVEmy134611/article/details/107212845 https://…...

C++ | 哈希表的实现与unordered_set/unordered_map的封装

目录 前言 一、哈希 1、哈希的概念 2、哈希函数 &#xff08;1&#xff09;直接定址法 &#xff08;2&#xff09;除留余数法 &#xff08;3&#xff09;平方取中法&#xff08;了解&#xff09; &#xff08;4&#xff09;随机数法&#xff08;了解&#xff09; 3、哈…...

【漏洞挖掘】Xray+rad自动化批量漏洞挖掘

文章目录 前言一、挖掘方法二、使用步骤工具安装使用方法开始挖掘 总结 前言 自动化漏洞挖掘是指利用计算机程序和工具来扫描、分析和检测应用程序、网络和系统中的安全漏洞的过程。这种方法可以帮助安全专家和研究人员更高效地发现和修复潜在的安全威胁&#xff0c;从而提高整…...

Swagger UI教程 API 文档和Node的使用

在团队开发中&#xff0c;一个好的 API 文档可以减少很多交流成本&#xff0c;也可以使一个新人快速上手业务。 前言 swagger ui是一个API在线文档生成和测试的利器&#xff0c;目前发现最好用的。为什么好用&#xff1f;Demo 传送门 支持API自动生成同步的在线文档 这些文档可…...

P5691 [NOI2001] 方程的解数

[NOI2001] 方程的解数 题目描述 已知一个 n n n 元高次方程&#xff1a; ∑ i 1 n k i x i p i 0 \sum\limits_{i1}^n k_ix_i^{p_i} 0 i1∑n​ki​xipi​​0 其中&#xff1a; x 1 , x 2 , … , x n x_1, x_2, \dots ,x_n x1​,x2​,…,xn​ 是未知数&#xff0c; k 1 ,…...