2021.6 更新
根據(jù)目前了解情況仙蚜,除查找技術(shù)解決方案外,還有可能向蘋(píng)果申請(qǐng)?zhí)厥鈾?quán)限來(lái)解決此問(wèn)題相种。關(guān)鍵詞:com.apple.developer.pushkit.unrestricted-voip
需求
公司項(xiàng)目有一套即時(shí)的視頻語(yǔ)音聊天功能,產(chǎn)品希望是當(dāng)App切入后臺(tái)掛起或者被用戶(hù)劃掉后,收到視頻語(yǔ)音推送時(shí)传蹈,App可以持續(xù)震動(dòng)及響鈴(持續(xù)震動(dòng)及響鈴),并且用戶(hù)點(diǎn)擊通知時(shí)步藕,App啟動(dòng)后就可以及時(shí)的進(jìn)行視頻語(yǔ)音通話(用戶(hù)無(wú)等待)惦界。
技術(shù)現(xiàn)狀
蘋(píng)果推送有三種方案:
1.普通推送
2.靜默推送
3.VoIP推送
針對(duì)三種推送方案的說(shuō)明,網(wǎng)上有很多很詳細(xì)的資料咙冗,這里就不一一列舉沾歪。我們很快的就可以鎖定,如果要實(shí)現(xiàn)以上需求雾消,VoIP是我們唯一可以選擇的方案灾搏。
在Xcode11之前,我們可以直對(duì)接VoIP推送立润,唯一面臨的是蘋(píng)果的審核狂窑。但是前段時(shí)間蘋(píng)果發(fā)布了一則通知:
Important
On iOS 13.0 and later, if you fail to report a call to CallKit, the system will terminate your app. Repeatedly failing to report calls may cause the system to stop delivering any more VoIP push notifications to your app. If you want to initiate a VoIP call without using CallKit, register for push notifications using the UserNotifications framework instead of PushKit. For more information, see UserNotifications.
通過(guò)Xcode11我們收到VoIP推送時(shí),如果我們沒(méi)有調(diào)用Callkit相關(guān)代碼桑腮,即reportNewIncomingCallWithUUID蕾域,我們會(huì)直接收到以下崩潰信息:
Apps receving VoIP pushes must post an incoming call (via CallKit or IncomingCallNotifications) in the same run loop as pushRegistry:didReceiveIncomingPushWithPayload:forType:[withCompletionHandler:] without delay.
*** Assertion failure in -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes], /BuildRoot/Library/Caches/com.apple.xbs/Sources/PushKit/PushKit-37/PKPushRegistry.m:343
顯然蘋(píng)果為了避免我們不正當(dāng)?shù)氖褂肰oIP推送,進(jìn)行了強(qiáng)制處理,所以我們需要對(duì)接CallKit咯旨巷?如果這樣做了巨缘,在提交的時(shí)候,以下信息可能在等著你:
Apple Dear Developer,
The Chinese Ministry of Industry and Information Technology (MIIT) http://www.miit.gov.cn/n1146285/ ... n3057713/index.html requested that CallKit functionality be deactivated in all apps available on the China App Store.
Since your app currently includes CallKit and is available for sale on the China App Store, you will need to submit an update that removes CallKit functionality in China.
VOIP call functionality continues to be allowed but can no longer take advantage of CallKit ’ s intuitive look and feel. CallKit can continue to be used in apps outside of China.
If you have questions or do not believe your app is subject to this update, please contact MIIT.
Best regards,
App Store Review
那我們通過(guò)手機(jī)號(hào)碼等條件采呐,進(jìn)行區(qū)域處理若锁。國(guó)內(nèi)使用普通推送,國(guó)外通過(guò)VoIP來(lái)做應(yīng)該可以通過(guò)蘋(píng)果要求斧吐,但是老板不同意了又固,我們面向的是國(guó)內(nèi)用戶(hù)。仿佛已經(jīng)撞到南墻了煤率!
另辟蹊徑
那讓我們先來(lái)對(duì)比下幾個(gè)大廠如何做的仰冠。
- QQ:收到視頻通話,手機(jī)持續(xù)震動(dòng)幾秒直至推送自動(dòng)隱藏蝶糯。點(diǎn)擊QQ無(wú)等待直接可以接聽(tīng)
- 微信:收到視頻通話洋只,手機(jī)持續(xù)震動(dòng)至少30s。點(diǎn)擊微信無(wú)需等待直接可以接聽(tīng)
- 閑魚(yú):收到視頻通話昼捍,手機(jī)震動(dòng)识虚,點(diǎn)擊閑魚(yú)后無(wú)需等待直接可以接聽(tīng)
BOSS: QQ、微信都實(shí)現(xiàn)了妒茬,你為什么實(shí)現(xiàn)不了担锤。。乍钻。
既然這些App都收到了VoIP推送并且激活了App肛循,同時(shí)沒(méi)有出現(xiàn)CallKit的電話界面,說(shuō)明通過(guò)某些方式是可以實(shí)現(xiàn)的银择。那我就把重點(diǎn)放在了當(dāng)我們調(diào)用reportNewIncomingCallWithUUID方法的時(shí)候多糠,系統(tǒng)做了什么。如果可以找到欢摄,那我們就可以偷偷地做個(gè)好心人幫系統(tǒng)做一下熬丧。
嘗試思路一
嘗試打印當(dāng)前所有線程內(nèi)的方法調(diào)用,看這個(gè)過(guò)程中怀挠,是否有一些不一樣的方法被調(diào)用析蝴,令人遺憾的是并沒(méi)有找到有用的信息。
嘗試思路二
監(jiān)聽(tīng)所有通知的發(fā)送绿淋,是否通過(guò)一些通知進(jìn)行了信息傳遞闷畸。這這個(gè)過(guò)程中,我們發(fā)現(xiàn)有一個(gè)不一樣的通知出現(xiàn):PKPushIncomingCallReportedNotification吞滞。
然后讓我們?cè)囋嚥辉僬{(diào)用reportNewIncomingCallWithUUID方法佑菩,而是發(fā)送這個(gè)通知呢盾沫?結(jié)果正是我們想要的!沒(méi)有CallKit的通話界面殿漠,App有沒(méi)有異常崩潰通知赴精。
存在的問(wèn)題
但是偶爾會(huì)出現(xiàn)無(wú)法再次收到VoIP的push通知。
高重現(xiàn)場(chǎng)景為:收到VoIP推送后長(zhǎng)時(shí)間不處理绞幌,客戶(hù)端會(huì)被異常終止蕾哟,之后就收不到了。但是收到時(shí)客戶(hù)端激活莲蜘,就沒(méi)有問(wèn)題谭确。
寫(xiě)在最后
目前工作有其他更緊急的插入進(jìn)來(lái),暫時(shí)沒(méi)有繼續(xù)研究了(后面抽時(shí)間再看)票渠。這里只是提供了一種解決問(wèn)題的思路逐哈,我們不能因?yàn)檎J(rèn)為做不到就不去嘗試。
如果有朋友有更好的思路或者存在問(wèn)題解決方案找到了问顷,可以回復(fù)用來(lái)幫助更多的人學(xué)習(xí)昂秃。
同時(shí)呢,這種方式只是我們挑戰(zhàn)自己的方式择诈,上架App還是要遵守蘋(píng)果規(guī)范的械蹋!