iOS10發(fā)布后输虱,簡書優(yōu)先開發(fā)增加了iOS10的新通知希痴。本文分享整個feature的開發(fā)過程遇到的問題际跪。
1躏敢、工程配置
Xcode8發(fā)生了很大的變化闷愤,直接打開原來的工程編譯運行,這個時候是獲取不到Push token的件余,打印didFailToRegisterForRemoteNotificationsWithError
中的error可以看到
fail to register with error Error Domain=NSCocoaErrorDomain Code=3000
"no valid 'aps-environment' entitlement string found for application"
UserInfo={NSLocalizedDescription=no valid 'aps-environment'
entitlement string found for application}
Google了解到是Xcode8的變化讥脐,entitlements
由本地的entitlements文件配置,主Target的Capabilities下啼器,Push Notification
處于關(guān)閉的狀態(tài)旬渠,必須手動打開。
2端壳、Code Sign
工程增加了Notification Content
和Notification Service
兩個Extension告丢,Signing
默認(rèn)是自動模式.。
據(jù)網(wǎng)上介紹Xcode8簽名管理方式比Xcode7更智能损谦,那我就試一下吧岖免。選完Team它就自動生成了授權(quán)文件。然而照捡,Xcode8還幫我生成了一個新的證書颅湘,相當(dāng)于增加了一個開發(fā)人員,也就是我現(xiàn)在的證書不在原來的授權(quán)文件中栗精,后果就是原來手動配置的授權(quán)文件要重新生成闯参。
這時候如果想使用原始的手動配置瞻鹏,不僅要把
Automatically manage signing
去掉,還要在Key Chains
里把新生成的證書刪掉鹿寨,然后在Web端生成授權(quán)文件新博。使用Automatically manage signing
最好把每個Target都使用相同的方式。
3释移、Swift版本
如果你在創(chuàng)建Target的時候開發(fā)語言選了Swift叭披,默認(rèn)是使用Swift3.0,Xcode8同時支持3.0和2.3玩讳,可能你還沒來及掌握3.0的API變化涩蜘,想繼續(xù)使用2.3的API,只要在對應(yīng)Target的Build Setting
中Use Legacy Swift Language Version
設(shè)為YES就可以繼續(xù)使用2.3熏纯。
4同诫、Architectures
工程配好之后,只有模板代碼樟澜,先跑起來寫個Hello World
再說误窖。Command+R
之后,編譯報錯了
Check dependencies
No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
VALID_ARCHS
中沒有對應(yīng)的active arch
這時需要在對應(yīng)Target的Build Setting
中Valid Architectures
中增加arm64
5秩贰、Notification Service
接下來霹俺,開始代碼編寫了,大部分是參考喵神的這篇文章活久見的重構(gòu) - iOS 10 UserNotifications 框架解析和Demo毒费、還有WWDC 708 Advanced Notifications丙唧、PDF。
在service中觅玻,我們會把后端push過來的數(shù)據(jù)中的圖片下載到本地文件夾想际,然后作為attachments。
之前我們的推送都只顯示一句alert溪厘,不過推送的json數(shù)據(jù)alert字段可以是string胡本,也可以是dictionary,如果是string畸悬,相當(dāng)于dictionary中的body
侧甫,在iOS8.2之后dictionary可以增加title
、subtitle
等蹋宦。為了讓推送更豐富闺骚,我們想把原來的body
變成title
,增加文章摘要放到body
里妆档,如果直接改aps
內(nèi)的alert
,那么8.2以前的設(shè)備推送顯示的是文章摘要了虫碉。后來我們想了一個辦法贾惦,Notification Service
不是可以修改推送內(nèi)容嗎?aps
的alert
還是保持不變,json增加一個新的title
和body
须板,Service收到通知之后把json中的title
和body
取出來賦給bestAttemptContent
的title
和body
碰镜。
{
"aps":{
"alert":"test test",
"mutable-content":1
},
"title": "new title",
"body": "new body"
}
6、Notification Content
如果通知有attachments习瑰,默認(rèn)情況下長按通知會顯示圖片或視頻绪颖,但是我們覺得顯示那么大一個圖片不美觀,而且要有action button甜奄,就是下面這種效果柠横,所以要用到Notification Content
。
其實這里沒有自定義通知的UI课兄,而是直接把這個View隱藏了牍氛。
Info.plist
中UNNotificationExtensionInitialContentSizeRatio
表示view的初始height/width(其他屬性參考WWDC),把它設(shè)為0.001(不能設(shè)為0)烟阐,在viewDidload
中設(shè)置self.preferredContentSize = CGSizeZero;
來隱藏view搬俊。這個Extension可以響應(yīng)多個
category
,而每個category
可以注冊自己的action buttons蜒茄,所以action buttons和customUI view是相互獨立的唉擂,不過可以通過action buttons更新customUI view。Action buttons默認(rèn)的行為會打開APP檀葛,由delegate處理響應(yīng)玩祟,使用了
Notification Content
后,我們可以在Notification Content
直接處理響應(yīng)而不用打開APP驻谆,也可以forward打開APP由delegate處理卵凑。
5、真機調(diào)試
代碼寫得差不多了胜臊,那就開始調(diào)試了勺卢。Extension調(diào)試過程中有時會遇到Could not attach to process ID <ID number>
錯誤。
有時重啟Xcode能解決象对,有時不能解決黑忱,這時候有一個方法,這個窗口彈出之后點
OK
勒魔,接著點Debug > Attach to Process > 你的Extension
甫煞,這時候就能捕獲斷點了。
6冠绢、提交TestFlight
測試過了準(zhǔn)備提交TestFlight抚吠,結(jié)果校驗出錯了。
錯誤信息很明顯弟胀,Extension.appex中包含了Frameworks文件夾楷力。如果Extension使用了Cocoapods喊式,Cocoapods會創(chuàng)建這個文件夾,實際沒什么用萧朝。解決辦法就是在
Build Phases
最后增加一個Build Phase
岔留,執(zhí)行一段shell腳本把Frameworks文件夾刪掉。
cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/"
if [[ -d "Frameworks" ]]; then
rm -fr Frameworks
fi
簡書每個版本都會進(jìn)行公測 公測詳情检柬,歡迎想要搶鮮的用戶前往下載體驗献联。
7、寫在最后
簡書作為一個優(yōu)質(zhì)原創(chuàng)內(nèi)容社區(qū)何址,擁有大量優(yōu)質(zhì)原創(chuàng)內(nèi)容里逆,提供了極佳的閱讀和書寫體驗,吸引了大量文字愛好者和程序員头朱。簡書技術(shù)團(tuán)隊在這里分享技術(shù)心得體會运悲,是希望拋磚引玉,吸引更多的程序員大神來簡書記錄项钮、分享班眯、交流自己的心得體會。這個專題以后會不定期更新簡書技術(shù)團(tuán)隊的文章烁巫,包括Android署隘、iOS、前端亚隙、后端等等磁餐,歡迎大家關(guān)注。