首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS15适配本地通知功能及语音播报探索

iOS15适配本地通知功能及语音播报探索

作者头像
玖柒的小窝
修改于 2021-11-05 06:51:01
修改于 2021-11-05 06:51:01
3.8K10
代码可运行
举报
文章被收录于专栏:各类技术文章~各类技术文章~
运行总次数:0
代码可运行

引言

一年一度的iOS 系统 API适配来了,9 月 14 日起 App Store Connect 已经开放 iOS 15 和 iPadOS 15 App 的提交,同时苹果宣布自 2022 年 4 月起,所有提交至 App Store 的 iOS 和 iPadOS app 都必须使用 Xcode 13 和 iOS 15 SDK 构建。

Xcode 13 正式版包含 iOS 15,iPadOS 15,tvOS 15,watchOS 8 以及 macOS Big Sur 11.3 SDKXcode 13 需在 macOS 11.3 及以上版本运行,支持 iOS 9,tvOS 9,watchOS 2 及以上系统设备调试; 也正式支持了 Vim。 Xcode 13 Release Notes: developer.apple.com/documentati…

I 消息推送

语音播报在iOS15之前的实现思路:

  1. 将你想要播放的音频拆分,放到主程序的包里
  2. 利用Service Extension,在收到服务端的推送的时候,按照顺序发送本地通知
  3. 本地通知的sound就是对应的音频拆分
  4. 将收到的推送的sound设置为nil,避免打断本地推送的语音播报。
  5. 设置队列处理消息推送,避免短时间内收到多个推送导致的问题。
  6. 设置本地通知不弹出横幅(iOS15失效了无法设置)

title和body都设置为空,或者注册通知的时候不启用UNAuthorizationOptionAlert,还要注意的是拓展里面需要设置一下本地化。 但是在iOS15如果body为空,将无法播放声音。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>

复制代码

1.1 本地推送适配

推送新特性: iOS15以上的新增属性 interruptionLevel为枚UNNotificationInterruptionLevel

需求:利用本地推送实现消息的语音播报(在扩展里面发本地通知,最后的接收方是主程序)

扩展在收到通知之后 -> 合成音频 -> 存储到扩展的对应路径 -> 扩展自己给自己发一个本地通知那个通知的sound设置成合成文件

iOS15之前的实现思路:

  1. 将你想要播放的音频拆分,放到主程序的包里
  2. 利用Service Extension,在收到服务端的推送的时候,按照顺序发送本地通知
  3. 本地通知的sound就是对应的音频拆分

问题:iOS12.1之后利用本地推送实现消息的语音播报,在iOS15 没有声音。kunnan.blog.csdn.net/article/det…

原因: iOS15本地推送新增了中断级别属性 interruptionLevel,对通知进行了分级 。而且通知的内容不能为空。

方案:使用非Passive的中断级别进行本地通知才会有声音,且本地推送一定要有内容,即body不能为空。content.body = @" 不能为空";

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        content.title = @"";
        content.subtitle = @"";
        content.sound = [UNNotificationSound soundNamed:fileName];
        content.badge = @(1);
        
        if (@available(iOS 15.0, *)) {
            content.interruptionLevel = UNNotificationInterruptionLevelTimeSensitive;//会使手机亮屏且会播放声音;可能会在免打扰模式(焦点模式)下展示
// @"{\"aps\":{\"interruption-level\":\"time-sensitive\"}}";
// @"{\"aps\":{\"interruption-level\":\"active\"}}";
            content.body = @" ";// 本地推送一定要有内容,即body不能为空。
            
        }else{
            
            content.body = @"";

        }
        
        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.001 repeats:NO];
        // 添加通知的标识符,可以用于移除,更新等操作
        NSString *identifier = [NSString stringWithFormat:@"localPushId%lld", (long long)[[NSDate date] timeIntervalSince1970]];
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
        [center addNotificationRequest:request withCompletionHandler:^(NSError *_Nullable error) {
            CGFloat waitTime = [self timeForAudioFileWithFileName:fileName];
//            CGFloat waitTime = 0.3;
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self localNotificationPushNextFile];
            });
        }];

复制代码

中断级别目前分为四种:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSUInteger, UNNotificationInterruptionLevel) {
    // Added to the notification list; does not light up screen or play sound
    UNNotificationInterruptionLevelPassive,
    
    // Presented immediately; Lights up screen and may play a sound
    UNNotificationInterruptionLevelActive,
    
    // Presented immediately; Lights up screen and may play a sound; May be presented during Do Not Disturb
    UNNotificationInterruptionLevelTimeSensitive,
    
    // Presented immediately; Lights up screen and plays sound; Always presented during Do Not Disturb; Bypasses mute switch; Includes default critical alert sound if no sound provided
    UNNotificationInterruptionLevelCritical,

} API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));

复制代码
  1. Passive:被动类型的通知不会使手机亮屏并且不会播放声音。
  2. Active: 活动类型的通知会使手机亮屏且会播放声音,为默认类型。
  3. Time Sensitive(时间敏感):会使手机亮屏且会播放声音;可能会在免打扰模式(焦点模式)下展示。

设置推送通知数据: 时间敏感的中断级别可以使用“interruption-level” payload key:{"aps":{"interruption-level":"time-sensitive"}} 时效性通知开发者无法直接使用,需要配置对应的权限: a. xcode 开启对应能力

b. 开发者后台配置appID支持该权限(通过Xcode开启对应能力通常会自动添加)

  1. Critical(关键):会立刻展示,亮屏,播放声音,无效免打扰模式,并且能够绕过静音,如果没有设置声音则会使用一种默认的声音。

适用于地震等紧急情况,需要特殊申请。

判断是否有时间敏感权限 @property(readonly, nonatomic) UNNotificationSetting timeSensitiveSetting;,如果没有需要提示用户开启。

UNNotificationSetting

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSInteger, UNNotificationSetting) {
    // The application does not support this notification type
    UNNotificationSettingNotSupported  = 0,
    
    // The notification setting is turned off.
    UNNotificationSettingDisabled,
    
    // The notification setting is turned on.
    UNNotificationSettingEnabled,
} API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0), tvos(10.0));

复制代码

1.2 测试

开发者想打ad hot 的话,需要能访问云端管理的分发证书。

可以使用极光的网页端或者接口进行测试,或者使用smart push。

1.3 升级JPush iOS SDK

v4.4.0: pod 'JPush' , '4.4.0'

docs.jiguang.cn/changelog/j… 更新时间:2021-10-28 Change Log: SDK适配ios15系统的本地通知功能 富媒体横屏异常兼容性处理

错误信息: ld: library not found for -ljcore-ios-2.3.4

原因:other linker flags 的信息没有自动更新

解决方案:直接删除other linker flags的jcore信息即可

II 解决新的问题:iOS15 使用本地通知会显示横幅

为了避免iOS15 使用本地通知会显示横幅,采取新的播放方案:Notification Service Extension接到通知之后,去解析出下载播放的音频,下载完毕之后修改sound字段,交由系统播报。

2.1 更换之前的实现思路

iOS15之后的系统通过Notification Service Extension修改推送sounds字段来播报自定义的语音。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
+ (instancetype)soundNamed:(UNNotificationSoundName)name;

复制代码

This method searches for sound files in the following locations, in order:

The <app_container>/Library/Sounds directory, where <app_container> is the app’s container directory.

The <group_container>/Library/Sounds directory, where <group_container> is one of the app’s shared group container directories. For information about how to configure group containers for your app, see Configure app groups.

The main bundle of the current executable.

sounds除了播放工程主目录(main bundle,打包时候就内置在项目中)和Library/Sounds,还可以播放AppGroup中Library/Sounds的音频 ,于是乎,我们可以在后台合成,然后下载到AppGroup后修改sound字段进行播放。

当音频下载处理完成后调用 self.contentHandler(self.bestAttemptContent); 弹出顶部横幅,并开始播报,横幅消失时音频会停止,音频需要控制在在6s之内;下载失败播放默认语音。

如果多条推送同时到达,调用self.contentHandler(self.bestAttemptContent);后,可主动去阻塞线程一定的时长(音频时长)。

2.2 注意事项

  1. 音频支持的格式: aiff、caf、wav、MP3
  2. 如果服务端不配合,不提供合成语音片段的下载地址,就需要在本地合成语音。

2.3 核心代码实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

        self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"sound.wav"];
   
    self.contentHandler(self.bestAttemptContent);


}
复制代码

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
bestAttemptContent.sound替换成功了,但是声音特别小,这个问题有遇到嘛?怎么解决
bestAttemptContent.sound替换成功了,但是声音特别小,这个问题有遇到嘛?怎么解决
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
iOS15 发送本地通知(附带声音)无法播报
iOS15版本下,配置UNNotificationSound来替换UNNotificationRequest声音,会出现没法播报问题
freesan44
2021/11/05
1.7K0
iOS15 推送动态语音播报解决方案
https://juejin.cn/post/7026639897289031687
freesan44
2021/12/29
1.3K0
推送-iOS本地通知
从 iOS 10 新增的 UserNotifications Framework 可以发现,Apple 整合了原有散乱的 API,并且增加了许多强大的功能。以 Apple 官方的角度来看,也必然是相当重视推送服务对 App 的影响、以及对 Apple iOS 生态圈长远发展的影响。
進无尽
2018/09/12
8K1
推送-iOS本地通知
写作小技能:卡片式写文章(用3-5张卡片写文)
什么是好文章?我认为一篇好的文章是分享保鲜期很长的内容,并会被大范围的传递,根据问题模型讲解最佳方案(问题 –> 方案 –> 总结):把复杂的问题讲解的很简单很清楚,有各种各样的推导和方案的比较( 原理、思路、方法论)。
公众号iOS逆向
2022/08/22
1.1K0
写作小技能:卡片式写文章(用3-5张卡片写文)
如何让iOS推送播放语音?
iOS 推送播放语音的需求调研,即收到推送后,播放推送的文案,文案的内容不固定。类似于支付宝和微信的收款到账语音。
莫空9081
2021/05/26
2.8K0
iOS 10前后两种本地通知
远程通知是指服务器发出的通知,通过苹果的推送然后到达用户设备。本地通知是指不通过网络,直接安装应用后就可以接到通知了,典型的例子是日历、待办、闹钟等应用。
Cloudox
2021/11/23
1.4K0
iOS 10前后两种本地通知
iOS13微信收款到账语音提醒开发总结
随着苹果爸爸在WWDC2019发布了新的iOS13,两年前的这篇微信iOS收款到账语音提醒开发总结方案已经不再适用,具体的原因是iOS13中(准确的说是使用XCode11编译)苹果不再允许PushKit应用在非voip电话的场景上。在iOS13中,苹果比以往更关注用户的隐私以及设备的电池续航问题,所以对PushKit的能力进行了收拢。如果需要使用PushKit的话则需要接入CallKit的接口,导致收到客户端收到Voip Push时会拉起一个接打电话的全屏界面,有在国区发布过应用的同学应该知道拉起这个界面是不被甲方允许的。这篇文章总结了在iOS13下的语音播报迁移方案以及一些需要注意的问题。目前微信的7.0.10版本已经带上了这部分的特性。
冰摇桃桃乌龙
2020/01/13
6.1K24
iOS 10 消息推送(UserNotifications)秘籍总结
单独整理消息通知的内容,但是因为工(就)作(是)的(很)事(懒)没有更新文章,违背了自己的学习的初衷。因为互联网一定要有危机意识,说不定眼一睁,我们就欧了 。
java爱好者
2019/06/19
3K0
ios入门之消息推送
前言 在去年的苹果大会上,苹果带来的iOS 10 系统中将之前繁杂的推送通知统一成UserNotifications.framework 来集中管理和使用通知功能,还增加一些实用的功能——撤回单条通知、更新已展示通知、中途修改通知内容、在通知中显示多媒体资源、自定义UI等功能。 那么在ios10之前,ios的消息推送是怎么分类的呢? ios 10之前 在ios之前,iOS推送分为Local Notifications(本地推送) 和 Remote Notifications(远程推送)。 本地推送 不需
xiangzhihong
2018/02/06
2.2K0
ios入门之消息推送
iOS10通知框架UserNotification理解与应用
        关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义,至于UI展示和用户交互行为相关的部分,开发者开发起来都十分困难。至于本地通知,iOS10之前采用的是UILocationNotification类,远程通知有苹果服务器进行转发,本地通知和远程通知其回调的处理都是通过AppDelegate中的几个回调方法来完成。iOS10系统中,通知功能的增强是一大优化之处,iOS10中将通知功能整合成了一个框架UserNotification,其结构十分类似于iOS8中的UIWebView向WebKit框架整合的思路。并且UserNotification相比之前的通知功能更加强大,主要表现在如下几点:
珲少
2018/08/15
2.1K0
iOS10通知框架UserNotification理解与应用
关于iOS实现前台,后台,锁屏或关闭app语音播报
公司要求像支付宝收款一样,收到推送后实现语音播报功能,之前没有做过,特此机会研究一下。 用到的技术点: 1.如果对语音要求不是特别高的情况下,用苹果系统自带的AVSpeechUtterance可以实现
honey缘木鱼
2018/06/13
3.9K1
iOS开发--本地通知与远程通知
1、NSNotification是系统内部发出通知,一般用于内部事件的监听,或者状态的改变等等,是不可见的 2、本地通知与远程通知是可见的,主要用于告知用户或者发送一些App的内容更新,推送一些相关的消息,让用户知道App内部发生了什么事情。
孙寅
2020/06/02
3.6K0
iOS14开发- 通知
远程通知是指在联网的情况下,由远程服务器推送给客户端的通知,又称 APNs(Apple Push Notification Services)。在联网状态下,所有设备都会与 Apple 服务器建立长连接,因此不管应用是打开还是关闭的情况,都能接收到服务器推送的远程通知。
YungFan
2021/11/24
2K0
iOS14开发- 通知
iOS12.1以上在后台或者被杀死无法语音播报的解决方案:用NotificationServiceExtension实现【修订】
iOS 10新增了Service Extension,这意味着在APNs到达我们的设备之前,还会经过一层允许用户自主设置的Extension服务进行处理,为APNs增加了多样性。
公众号iOS逆向
2021/04/30
1.6K0
iOS12.1以上在后台或者被杀死无法语音播报的解决方案:用NotificationServiceExtension实现【修订】
iOS 本地推送概念步骤:属性:点击通知跳到指定控制器界面快捷回复功能(iOS 8以后可用), category 属性的使用方法
概念 1.推送通知有5种不同的呈现效果 在屏幕顶部显示一块横幅(显示具体内容) 在屏幕中间弹出一个UIAlertView(显示具体内容) 在锁屏界面显示一块横幅(锁屏状态下,显示具体内容) 更新app图标的数字(说明新内容的数量) 播放音效(提醒作用) 2.用户也可以决定是否要开启以下4个功能: 显示App图标数字 播放音效 锁屏显示 显示在“通知中心” 3、注意: 发送推送通知时,如果程序正在前台执行,那么推送通知就不会被呈现出来,但是微信在前台的时候也能推送消息,方法是:创建一个view,仿造系统消息通
用户2141756
2018/05/18
2.9K0
Android7.1.1系统设置默认值大全
1,是否有默认值 在寻找一个开关的默认值时,首先要明白一点,该开关是否存在默认值,以及该开关状态是否有状态保存(一般状态存储在settings的db中)。 判断条件: 在reboot(重启)之后开关状态仍旧保存或者是在reset(恢复出厂设置)之后开关状态恢复到默认的,才能找到默认值。 在reboot之后开关状态仍旧保存的,表示状态存储在了db中。 在reset之后开关状态恢复默认的,表示状态有一个默认值。 比如像wiif开关,蓝牙开关,gps开关等,都有默认值,并且状态值都在db中保存。
fanfan
2018/01/24
4K0
React Native 常用的 15 个库
本篇 React native 库列表不是从网上随便找的, 这些是我在我的应用中亲自使用的库。 这些库功能可能跟其它库也有,但经过大量研究并在我的程序中尝试后,我选择了这些库。
前端小智@大迁世界
2019/04/25
6.8K0
React Native 常用的 15 个库
iOS小技能: 限制账号退出登陆后无法收到推送功能(递归设置和删除别名)
⭕ 解决iOS15之后本地通知通知栏弹出多次的问题:使用Service Extension拦截消息推送,修改UNNotificationSound为本地拼接的音频,来避免产生多条横幅。
公众号iOS逆向
2022/08/22
1.9K0
iOS小技能: 限制账号退出登陆后无法收到推送功能(递归设置和删除别名)
iOS中使用本地通知为你的APP添加提示用户功能
首先,我们先要明白一个概念,这里的本地通知是UILocalNotification类,和系统的NSNotificationCenter通知中心是完全不同的概念。
珲少
2018/08/15
9450
iOS 点击推送消息跳转指定界面 —总结篇app 在后台app被杀死
收到推送的准备: 首先至于说消息推送的原理,证书配置等等这些我在这里就不在累述,有很多写的很好的文章相信您已经可以搞定这块,这里我重点讲下各种情况下的跳转处理。 点击推送触发的几个方法: ios7.0之前 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{ // App 收到推送的通知 NSLog(@"********** ios7.
陈雨尘
2018/06/07
8.7K1
推荐阅读
相关推荐
iOS15 发送本地通知(附带声音)无法播报
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验