iOS推送-后台、锁屏和杀死情况下播放合成语音并相关执行代码(类似微信收款码语音)

1,311 阅读3分钟

首先,有同学在后台问我推送合成自定义语音播放的问题,这篇文章是对上篇文章的补充。

阅读本篇文章可以先浏览一下我之前写的后台推送相关,重复的内容就不在赘述了。

iOS极光推送,后台和锁屏状态下播放推送过来的信息 在线合成语音请看我之前写的文章 iOS 文字转语音的三种方案

之前的文章是用极光的推送写的,现在我使用的个推,不过并不影响我们的实现。

前台不再赘述 有问题可以问我!

首先,我们看下远程消息的回调

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler 

普通推送:收到推送后(有文字有声音),点开通知,进入APP后,才执行 静默推送:收到推送(没有文字没有声音),不用点开通知,不用打开APP,就能执行,用户完全感觉不到,可以理解允许应用在收到通知后在后台运行一段代码,且能够马上执行

静默推送的使用:

如果只携带content-available: 1 不携带任何badge,sound 和消息内容等参数,则可以不打扰用户的情况下进行内容更新等操作。

这样即可以实现在后台合成语音和数据的增删改查等操作。

后台语音播放

如果想使用合成语音在后台进行播放,必须支持后台语音。

image.png

- (void)applicationWillResignActive:(UIApplication *)application
{
    if (_bgTaskId == UIBackgroundTaskInvalid) {
        _bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
    }
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if (_bgTaskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:_bgTaskId];
        _bgTaskId = UIBackgroundTaskInvalid;
    }
}

- (UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId
{
    
    // 1. 设置并激活音频会话类别
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback error: nil];
    [session setActive:YES error:nil];
    
    // 2. 允许应用程序接收远程控制
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
    
    // 3. 设置后台任务ID
    UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
    
    newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    
    if (newTaskId != UIBackgroundTaskInvalid && backTaskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:backTaskId];
    }
    return newTaskId;
}

你有可能发现它有时候在后台播着播着它就无故停止了,其实并不是无故,而是有故的。就是因为app进入后台运行时其实并不是后台运行,只有有限的时间让你处理一些必要的保存等操作,然后app就会被挂起了。 例如:beginBackgroundTask endBackgroundTask;

这样就可以实现后台的语音播放了,语音合成请看文章开头。

本地推送

接下来,我们会发现我现在可以根据数据播放自定义的语音了,但是在静默模式下并没有推送的弹框,这样就需要我们用本地推送来模拟远程推送的弹出效果。

- (void)registerLocalNotification {
    if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
        // 设置通知的类型可以为弹窗提示,声音提示,应用图标数字提示
        UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil];
        // 授权通知
        [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
    }
}

- (void)popLocalNotificationWithPlayMsg:(NSString *)playMsg {
    
    // 1.创建通知
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    // 2.设置通知的必选参数
    // 设置通知显示的内容
    localNotification.alertBody = playMsg;
    // 设置通知的发送时间,单位秒
    localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
    //解锁滑动时的事件
    localNotification.alertAction = @"";
    //收到通知时App icon的角标
    //localNotification.applicationIconBadgeNumber = 1;
    //推送是带的声音提醒,设置默认的字段为UILocalNotificationDefaultSoundName
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    
    // 3.发送通知
    //一: 根据通知的发送时间(fireDate)发送通知
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    //二: 立即发送通知
    // [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}

这样就实现了 类似于微信收款码一样的服务,无论是在前台、后台、锁屏和离线的情况下都会收到推送合成在线语音并处理数据。