iOS 后台语音播报功能开发过程中的坑

40 阅读2分钟

先创建UNNotificationServiceExtension target

image.png

Service ExtensionBundle Identifier不能和Main Target(也就是你自己的App Target)的Bundle Identifier相同,否则会报BundeID重复的错误。
Service Extension的Bundle Identifier需要在Main Target的命名空间下,比如说Main Target的BundleID为io.jpush.xxx,那么Service Extension的BundleID应该类似与io.jpush.xxx.yyy这样的格式。如果不这么做,你可能会遇到一个错误。
创建好了把相关音频文件导入:

image.png

在下面方法做相关数据处理

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

    // Modify the notification content here... //self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];

    [[AVAudioSession sharedInstance] setActive:YES error:NULL]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; NSDictionary *userInfo = self.bestAttemptContent.userInfo; NSDictionary * aps = [userInfo objectForKey:@"aps"]; NSString * soundCommand = [aps valueForKey:@"soundCommand"]; [self playSoundsWithSoundCommand:soundCommand]; self.contentHandler(self.bestAttemptContent); } /播放/ -(void)playWithFileUrlString:(NSString *)fileURLString{ if (![fileURLString length]) { return; } AVAudioSession * session = [AVAudioSession sharedInstance]; [session setActive:YES error:nil]; BOOL ret = [session setCategory:AVAudioSessionCategoryPlayback error:nil]; NSLog(@"%d",ret); NSURL *fileURL = [[NSBundle mainBundle]URLForResource:fileURLString withExtension:@".mp3"];

    static SystemSoundID soundID = 0;

    AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(fileURL), &soundID);

    AudioServicesPlayAlertSoundWithCompletion(soundID, ^{ NSLog(@"播放完成"); }); }

记住了在做完相关操作之后再调用self.contentHandler(self.bestAttemptContent);方法 进入墓碑模式(不执行应用程序的任何代码)
还有很重要的一点,记住push的试试让后台同学要加入一个参数"mutable-content" = 1;,不然我们的扩展类方法是拦截不到推送的哦,要和alert 同级的,位置不要错。

image.png

接下来运行-测试,完美实现。打包,然后又报错了,看了原因是因为扩展target和我的原来工程的签名不是同一team,这时候就要用的appid创建的时候创建一个通配符appid了。
在你开发者中心创建一个通配符appid包含到你的扩展应用下,然后生成相关开发和生成Profile文件,下载下来,然后打包。成功!!!

重要补充:

  在iOS12.1之后苹果爸爸禁用了UNNotificationServiceExtension 在后台使用AVAudioSession播放语音文件,解决方法是我们拿到- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler方法里面的bestAttemptContent给他的sound赋值一下就OK了。

self.bestAttemptContent.sound = [UNNotificationSound soundNamed:[NSString stringWithFormat:@"%@.mp3",fileURLString]];

这里提一下如果用这种方法播放语音文件相应的语音资源需要导入到主程序中,不能放在UNNotificationServiceExtension中。