引言
前两天产品经理希望在B端的App上实现订单通知的语音提醒功能,类似于微信、支付宝的收款到账通知。遂展开调研,最终在拜读各位大佬的文章后,终于基于 Notification Service Extension 实现此功能,在此记录一笔。
何为 Notification Service Extension
Notification Service Extension 是 iOS 10 推出的系统扩展。它提供了对远程推送通知消息
的拦截预处理功能。
实现思路
创建一个推送扩展(Notification Service Extension)
,在远程通知消息到达时进行拦截并解析消息中的内容,再根据订单类型,对通知的声音差异化设置。从而达到播放不同的语音的目的。
1. 创建 Extension 的 AppID
Extension
是依赖于主App的插件。其生命周期受系统管理,不受主App管理。首先我们需要登录苹果的开发者账号,为推送扩展
创建它自己的App ID
。
创建ID时,我在
capabilities
中选中了App Group
项。App Group
用于创建Extension
与主App的共享数据空间。方便以后存储在线生成的语音文件,用来播报订单号与金额。(写本文时没有这个需求,所以暂时不用设置)
2. 创建描述文件 Profile
按照正常流程,创建Extension
的描述文件。
3. 项目工程添加 Notification Extendsion
3.1 主工程配置
主工程的Background Mode
按照如下勾选:
3.2 创建扩展
点击 File -> New -> Target,创建一个Notification Service Extension
。
3.3 配置扩展
创建完成后,导入描述文件。
4. 生成语音文件
经过上面的步骤,我们的扩展已经配置完成。下面继续生成语音文件。由于目前项目中订单的各种状态所对应的提示是固定的。所以直接使用科大讯飞的在线语音合成,得到不同的语音文件。
目前语音文件统一放到了主项目中的Resource文件目录下:
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模拟远程推送通知消息。具体的消息格式,请自行查阅推送平台的文档说明。
最重要的是,如果希望
Notification Extension
生效,那么mutable-content
字段必须设置为 1
。