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

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

引言

一年一度的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 SDK。Xcode 13 需在 macOS 11.3 及以上版本运行,支持 iOS 9,tvOS 9,watchOS 2 及以上系统设备调试;

也正式支持了 Vim。

Xcode 13 Release Notes: https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes

image.png

I 消息推送

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

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

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

<key>CFBundleDevelopmentRegion</key>
 <string>$(DEVELOPMENT_LANGUAGE)</string>

1.1 本地推送适配

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

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

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

iOS15之前的实现思路:

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

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

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

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

image.png

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];
            });
        }];

中断级别目前分为四种:

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 开启对应能力

image.png

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

image.png

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

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

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

UNNotificationSetting

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 的话,需要能访问云端管理的分发证书。

image.png

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

image.png

1.3 升级JPush iOS SDK

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

https://docs.jiguang.cn/changelog/jpush/updates_iOS/

更新时间:2021-10-28

Change Log:

SDK适配ios15系统的本地通知功能

富媒体横屏异常兼容性处理

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

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

image.png

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

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

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

2.1 更换之前的实现思路

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

+ (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 核心代码实现

@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);
}

下载完在本地修改sound字段,交由系统播报

完整代码请看原文:https://kunnan.blog.csdn.net/article/details/121108318

see also

目录
相关文章
|
4月前
|
存储 数据建模 iOS开发
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
iOS设备功能和框架: 什么是 Core Data,它在 iOS 中的作用是什么?
34 1
|
4月前
|
定位技术 iOS开发
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
iOS设备功能和框架: 如何使用 Core Location 获取设备的位置信息?
20 0
|
8月前
|
移动开发 安全 前端开发
提升iOS应用安全性:全面代码混淆功能介绍,使用Ipa Guard保护你的应用
iOS加固保护是直接针对ios ipa二进制文件的保护技术,可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护,防止应用程序中的代码及资源文件被恶意篡改。Ipa Guard通过修改 ipa 文件中的 macho 文件中二进制数据(代码模块配置)进行操作,无需源码。不限定开发技术平台。支持oc,swift,cocos2d-x、unity3d、quick-cocos,html5 ,react native等等各种开发技术。Ipa Guard主要包含代码混淆全面、资源文件处理、不需要源代码更安全、调试信息清理、即时测试运行。
|
9月前
|
监控 Android开发 iOS开发
盘点一对一直播源码iOS系统维持平台稳定功能(一):弹性扩缩容
参考代码:弹性扩缩容如何实现?System.out.println("扩容:增加直播平台实例"); currentCapacity++; } private void scaleDown() { System.out.println("缩容:减少直播平台实例");
盘点一对一直播源码iOS系统维持平台稳定功能(一):弹性扩缩容
|
移动开发 前端开发 iOS开发
记录一下前端H5的复制功能在ios端的兼容性问题
记录一下前端H5的复制功能在ios端的兼容性问题
720 0
|
iOS开发
IOS - iOS 12 的“隐式推送”功能怎么用?
IOS - iOS 12 的“隐式推送”功能怎么用?
332 0
IOS - iOS 12 的“隐式推送”功能怎么用?
|
4月前
|
机器学习/深度学习 PyTorch TensorFlow
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
iOS设备功能和框架: 什么是 Core ML?如何在应用中集成机器学习模型?
35 0
|
4月前
|
iOS开发
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
101 0
|
9月前
|
存储 视频直播 iOS开发
山东布谷科技iOS端实现直播app源码秒开技术(二):缓冲功能
缓冲功能对直播app源码平台用户有着提升观看短视频、直播体验的作用;对直播app源码平台有着提升直播质量,增加观众黏性的好处。因此,直播平台应当重视并充分发挥缓冲功能的潜力,为用户继续打造更好的直播观看体验。
山东布谷科技iOS端实现直播app源码秒开技术(二):缓冲功能