Notification Service Extension 实现语音播报

5,226 阅读3分钟

引言

前两天产品经理希望在B端的App上实现订单通知的语音提醒功能,类似于微信、支付宝的收款到账通知。遂展开调研,最终在拜读各位大佬的文章后,终于基于 Notification Service Extension 实现此功能,在此记录一笔。

何为 Notification Service Extension

Notification Service Extension 是 iOS 10 推出的系统扩展。它提供了对远程推送通知消息的拦截预处理功能。

实现思路

创建一个推送扩展(Notification Service Extension),在远程通知消息到达时进行拦截并解析消息中的内容,再根据订单类型,对通知的声音差异化设置。从而达到播放不同的语音的目的。

1. 创建 Extension 的 AppID

Extension是依赖于主App的插件。其生命周期受系统管理,不受主App管理。首先我们需要登录苹果的开发者账号,为推送扩展创建它自己的App IDimage.png

创建ID时,我在capabilities中选中了App Group项。App Group用于创建Extension与主App的共享数据空间。方便以后存储在线生成的语音文件,用来播报订单号与金额。(写本文时没有这个需求,所以暂时不用设置)

image.png

2. 创建描述文件 Profile

按照正常流程,创建Extension的描述文件。 image.png

3. 项目工程添加 Notification Extendsion

3.1 主工程配置

主工程的Background Mode按照如下勾选: image.png

3.2 创建扩展

点击 File -> New -> Target,创建一个Notification Service Extensionimage.png image.png

3.3 配置扩展

创建完成后,导入描述文件。 image.png

4. 生成语音文件

经过上面的步骤,我们的扩展已经配置完成。下面继续生成语音文件。由于目前项目中订单的各种状态所对应的提示是固定的。所以直接使用科大讯飞的在线语音合成,得到不同的语音文件。

目前语音文件统一放到了主项目中的Resource文件目录下: image.png

5. Extension 编码

完成Extendsion配置,并准备好语音文件后。我们可以进入到编码部分。 对远程推送的拦截处理,都集中在NotificationService.m文件。

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
  self.contentHandler = contentHandler;
  self.bestAttemptContent = [request.content mutableCopy];
  
  /// 解析推送消息
  NSMutableDictionary *extras = [NSMutableDictionary dictionaryWithDictionary: self.bestAttemptContent.userInfo];
  /// 拿到订单类型
  NSNumber *msgType = extras[@"msgType"];
  /// 根据订单类型,拿到对应音频文件名称
  NSString *soundName = [self soundNameByNotifyType:msgType.integerValue];
  /// 差异化设置推送声音
  self.bestAttemptContent.sound = ISNOTEMPTY_STRING(soundName) ? [UNNotificationSound soundNamed:soundName] : [UNNotificationSound defaultSound];
  NSLog(@"(%@)%@", soundName, msgType);
  
  self.contentHandler(self.bestAttemptContent);
}

-(NSString *)soundNameByNotifyType:(MDBShopMallOrderType)type{
  NSString *soundName = @"";
  switch (type) {
      case MDBShopMallOrderTypeNew:
          soundName = @"新订单.mp3";
          break;
      case MDBShopMallOrderTypeWriteOff:
          soundName = @"核销.mp3";
          break;
      case MDBShopMallOrderTypeError:
          soundName = @"配送异常.mp3";
          break;
      case MDBShopMallOrderTypeRefund:
          soundName = @"退款.mp3";
          break;
      default:
          soundName = @"";
          break;
  }
  return soundName;
}

调试

我使用Knuff模拟远程推送通知消息。具体的消息格式,请自行查阅推送平台的文档说明。 image.png 最重要的是,如果希望Notification Extension生效,那么mutable-content字段必须设置为 1

感谢

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

iOS13微信收款到账语音提醒开发总结