iOS 推送(殺死進(jìn)程,獲取推送消息并播放語(yǔ)音)

該功能為推送高級(jí)功能,主要講解app殺死進(jìn)程或者后臺(tái)情況下收到推送后募强,播放語(yǔ)音坠非。實(shí)際該需求呢希柿,就是類似于支付寶在沒有運(yùn)行的情況下收到推送消息腐芍,然后播報(bào)收錢的功能,接下來(lái)給大家講解一下具體配置以及代碼實(shí)現(xiàn)被啼。

一帜消、首先需要大家了解下iOS 10 UNNotificationServiceExtension 這個(gè)類。

1.選擇創(chuàng)建“NotificationServiceExtension”

第一步浓体,先選擇新建 NEW——>Target


創(chuàng)建Target.png

第二步泡挺,選擇UNNotificationServiceExtension擴(kuò)展類,不是左邊的汹碱,他們的用途不一樣,UNNotificationContentExtensior主要用戶自定義推送UI


UNNotificationServiceExtension.jpg

第三步荞估,擴(kuò)展類的名字可以隨便起咳促,根據(jù)自己的愛好
VocalPush

創(chuàng)建完成之后,項(xiàng)目中會(huì)多一個(gè)VocalPush目錄勘伺,且Scheme中也同樣增加VocalPush


截屏2020-09-02 20.44.13.png

二跪腹、配置擴(kuò)展

1.添加功能支持


image.png

2.info.plist中:添加“App Transport Security Settings”字典 ,字典中添加“Allow Arbitrary Loads”設(shè)置為YES


image.png

3.把擴(kuò)展里的Deployment Target 改成 10.0之后版本飞醉,因?yàn)?0.0之后才支持推送擴(kuò)展
6601599058908_.pic.jpg

4.基本完成配置工作冲茸,要想體驗(yàn)效果,先運(yùn)行一下擴(kuò)展缅帘,然后再選擇運(yùn)行一下項(xiàng)目轴术。


6611599059106_.pic.jpg

5.后端發(fā)推送消息的時(shí)候,改方式一定要注意,在aps里一定要有"mutable -content"這個(gè)字段,值為1钦无。不設(shè)置mutable -content = 1逗栽,不能實(shí)現(xiàn)該方式推送處理。
{
  "aps" : {
    "content-available" : 1,
    "alert" : {
      "title" : "通知",
      "body" : "XTH到賬45元"
    },
    "badge" : 0,
    "sound" : "default"
  }
}

三失暂、代碼實(shí)現(xiàn)處理

1.NotificationService.m文件內(nèi)的代碼彼宠,就是iOS10的推送擴(kuò)展鳄虱。

實(shí)際使用的是設(shè)置self.bestAttemptContent.sound的方式,而現(xiàn)階段蘋果也只能通過(guò)設(shè)置該屬性去實(shí)現(xiàn)播放語(yǔ)音的功能凭峡。在我的項(xiàng)目中用的是提前錄制好的語(yǔ)音文件拙已,而支付寶,是使用文字轉(zhuǎn)語(yǔ)音文件的方式摧冀,之后再設(shè)置該屬性去實(shí)現(xiàn)的語(yǔ)音播放倍踪,你也可以通過(guò)網(wǎng)絡(luò)下載語(yǔ)音文件之后播放的方式去實(shí)現(xiàn)同樣的效果。
網(wǎng)上有很多比較老的文章按价,筆者在研究此功能的時(shí)候也走了不少?gòu)澛凡咽剩热缭跀U(kuò)展類NotificationService中,實(shí)現(xiàn)系統(tǒng)語(yǔ)音播報(bào)MediaPlayer楼镐,AVFoundation去語(yǔ)音轉(zhuǎn)文字播放癞志,或者直接播放語(yǔ)音文件都是不能實(shí)現(xiàn)該功能的,但是iOS10.0是可以實(shí)現(xiàn)的框产,根據(jù)大量閱讀蘋果開發(fā)文檔凄杯,蘋果起初設(shè)計(jì)該擴(kuò)展類的目的是優(yōu)化推送樣式,不是為了語(yǔ)音處理秉宿,但是發(fā)現(xiàn)大部分開發(fā)者通過(guò)這種方式處理語(yǔ)音播放問(wèn)題戒突,所以后來(lái)把所有播放語(yǔ)音類的代碼,讓其在UNNotificationServiceExtension擴(kuò)展類中的代碼都是無(wú)效的描睦。但是self.bestAttemptContent仍包含的有sound屬性膊存,所以后來(lái)大家都通過(guò)處理過(guò)后生成的語(yǔ)音文件,賦值給self.bestAttemptContent.sound去實(shí)現(xiàn)播放語(yǔ)音的效果忱叭。

#import "NotificationService.h"
@interface NotificationService ()<AVAudioPlayerDelegate,AVSpeechSynthesizerDelegate>

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

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

#pragma mark -
//    // 重寫一些東西
//     self.bestAttemptContent.title = @"我是標(biāo)題";
//     self.bestAttemptContent.subtitle = @"我是子標(biāo)題";
//     self.bestAttemptContent.body = @"來(lái)自徐不同";

    NSDictionary *userInfoDic =  self.bestAttemptContent.userInfo;
    NSLog(@"后臺(tái)推送消息內(nèi)容:%@",userInfoDic);
    // 安全預(yù)警提醒類型
    if ([userInfoDic[@"pushType"] isEqualToString:@"SAFETY_WARNING"]) {
        // 12.1系統(tǒng)版本之前 可以是用AVAudioSession
        if ([[[UIDevice currentDevice] systemVersion]floatValue] < 12.1) {
            // AVAudioSession是一個(gè)單例類
            AVAudioSession *session = [AVAudioSession sharedInstance];
            // AVAudioSessionCategorySoloAmbient是系統(tǒng)默認(rèn)的category
            [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
            // 激活A(yù)VAudioSession
            [session setActive:YES error:nil];

            // 文字轉(zhuǎn)語(yǔ)音播放
            [self playVoiceWithContent:userInfoDic[@"content"]];
        } else {
            if ([userInfoDic[@"sinoiovNoticeType"] isEqualToString:@"SPEEDING"]) {
                // SPEEDING 超速
                self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"overSpeed.m4a"];
                NSLog(@"超速");
            }else if ([userInfoDic[@"sinoiovNoticeType"] isEqualToString:@"FATIGUE"]) {
                // FATIGUE 疲勞
                self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"fatigueDriving.m4a"];
                NSLog(@"疲勞");
            }else if ([userInfoDic[@"sinoiovNoticeType"] isEqualToString:@"VEHICLE_OFFLINE"]) {
                // VEHICLE_OFFLINE 離線
                self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"offLine.m4a"];
                NSLog(@"離線");
            }else if ([userInfoDic[@"sinoiovNoticeType"] isEqualToString:@"PARKING_VIOLATION"]) {
                // PARKING_VIOLATION 高速公路違規(guī)停車
                self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"illegalParking.m4a"];
                NSLog(@"高速公路違規(guī)停車");
            }else if ([userInfoDic[@"sinoiovNoticeType"] isEqualToString:@"LOW_SPEED"]) {
                // LOW_SPEED 高速公路低速行駛
                self.bestAttemptContent.sound = [UNNotificationSound soundNamed:@"lowSpeed.m4a"];
                NSLog(@"高速公路低速行駛");
            }
            self.contentHandler(self.bestAttemptContent);
        }
    }else {
        // 直接彈出推送框
        self.contentHandler(self.bestAttemptContent);
    }
}

- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    self.contentHandler(self.bestAttemptContent);
}
@end

需要注意的是:
1.以上擴(kuò)展方法中是不能打斷點(diǎn)的隔崎,打斷點(diǎn)會(huì)導(dǎo)致崩潰且找不到原因,需要打印數(shù)據(jù)使用NSLog方法韵丑,打斷點(diǎn)會(huì)崩潰的問(wèn)題不是個(gè)例爵卒。
2.該種方式的推送語(yǔ)音消息只支持6s時(shí)間,因?yàn)橄到y(tǒng)的推送彈框的顯示時(shí)間為6s撵彻,超過(guò)6s的語(yǔ)音會(huì)停止播放钓株,請(qǐng)注意語(yǔ)音時(shí)長(zhǎng),因?yàn)闀r(shí)間原因陌僵,本人沒有做深入研究是否可以延長(zhǎng)推送彈框的方法轴合。
以上問(wèn)題有哪位大神知道原因或者有解決辦法,可以聯(lián)系告知筆者碗短。

2.以上代碼只是實(shí)現(xiàn)了語(yǔ)音播報(bào)的功能值桩,實(shí)際上蘋果支持,自定義推送彈框樣式豪椿,需要使用UNNotificationContentExtensior去實(shí)現(xiàn)奔坟。但是系統(tǒng)也自帶的有默認(rèn)的圖片樣式以及后臺(tái)下載音樂文件携栋,視頻文件點(diǎn)擊播放的功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載咳秉,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者婉支。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市澜建,隨后出現(xiàn)的幾起案子向挖,更是在濱河造成了極大的恐慌,老刑警劉巖炕舵,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件何之,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咽筋,警方通過(guò)查閱死者的電腦和手機(jī)溶推,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奸攻,“玉大人蒜危,你說(shuō)我怎么就攤上這事《媚停” “怎么了辐赞?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)硝训。 經(jīng)常有香客問(wèn)我响委,道長(zhǎng),這世上最難降的妖魔是什么窖梁? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任赘风,我火速辦了婚禮,結(jié)果婚禮上窄绒,老公的妹妹穿的比我還像新娘贝次。我一直安慰自己崔兴,他們只是感情好彰导,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著敲茄,像睡著了一般位谋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堰燎,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天掏父,我揣著相機(jī)與錄音,去河邊找鬼秆剪。 笑死赊淑,一個(gè)胖子當(dāng)著我的面吹牛爵政,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播陶缺,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼钾挟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了饱岸?” 一聲冷哼從身側(cè)響起掺出,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苫费,沒想到半個(gè)月后汤锨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡百框,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年闲礼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琅翻。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡位仁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出方椎,到底是詐尸還是另有隱情聂抢,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布棠众,位于F島的核電站琳疏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闸拿。R本人自食惡果不足惜空盼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望新荤。 院中可真熱鬧揽趾,春花似錦、人聲如沸苛骨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)痒芝。三九已至俐筋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間严衬,已是汗流浹背澄者。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粱挡。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓赠幕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親询筏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子劣坊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359