轉(zhuǎn)自:http://blog.csdn.net/u012361288/article/details/51656569
近期發(fā)現(xiàn)一個蛋疼的問題,iOS里清程序角標(biāo)的時(shí)候會把通知欄的推送消息也清了潘鲫。試驗(yàn)了好久得到了一些結(jié)論肮蛹,記錄下結(jié)果儒飒。
推送分為遠(yuǎn)程推送和本地推送舵盈。分開來記錄论矾。
在遠(yuǎn)程推送的協(xié)議中剃允,有一個badge字段沛简,這個字段是用來設(shè)置程序角標(biāo)值的齐鲤。當(dāng)app處于非運(yùn)行狀態(tài)或者在后臺時(shí),收到遠(yuǎn)程推送椒楣,app并不會運(yùn)行任何代碼给郊,一切事務(wù)都是由系統(tǒng)處理(iOS 7推出的靜默推送是特例)。此時(shí)收到推送捧灰,系統(tǒng)會根據(jù)推送消息的aps里的內(nèi)容執(zhí)行操作淆九,包括:"sound"-提示音、"alert"-通知欄顯示的推送內(nèi)容毛俏、"badge"-程序角標(biāo)值炭庙、"content-available"-靜默推送標(biāo)志。sound煌寇、alert和content-available就不提了焕蹄,單說badge。分為下面幾種情況:
- 收到推送前程序角標(biāo)為零阀溶,收到的推送消息badge為0腻脏。此時(shí)角標(biāo)一直處于為零的狀態(tài)(為零時(shí)不顯示角標(biāo))。
- 收到推送前程序角標(biāo)為零银锻,收到的推送消息badge大于0永品。此時(shí)角標(biāo)從不顯示變?yōu)閎adge的值。
- 收到推送前程序角標(biāo)不為零徒仓,收到的推送消息badge為0腐碱。此時(shí)角標(biāo)從顯示變?yōu)椴伙@示誊垢,且清空所有通知欄的消息掉弛,包括新收到的推送消息。(此處測試的情況是喂走,當(dāng)收到推送前角標(biāo)不為0殃饿,收到的推送消息badge為0或小于0時(shí),角標(biāo)保持不變)芋肠。
- 收到推送前程序角標(biāo)不為零乎芳,收到的推送消息badge大于0。此時(shí)角標(biāo)值更新帖池。
本地推送通過UILocalNotification對象發(fā)送奈惑,UILocalNotification有一個applicationIconBadgeNumber屬性,作用與遠(yuǎn)程推送的badge字段類似睡汹,針對上而的四種情況肴甸,結(jié)果與遠(yuǎn)程推送相同。但需要注意一點(diǎn):當(dāng)applicationIconBadgeNumber設(shè)為零(也是默認(rèn)值)時(shí)囚巴,意味著不改變程序角標(biāo)原在,而不是將程序角標(biāo)置零友扰。當(dāng)applicationIconBadgeNumber < 0時(shí),程序角標(biāo)變?yōu)椴伙@示庶柿,通知欄通知不清零村怪。順帶說一下UILocalNotification的cancelLocalNotification:和cancelAllLocalNotification方法,這兩個方法是清除那些在日程表中尚未推送的本地推送消息浮庐,而不是清除通知欄內(nèi)的推送消息甚负。通知欄內(nèi)的消息完全由系統(tǒng)控制,程序無法獲得兔辅。只有當(dāng)用戶點(diǎn)擊了通知欄的消息腊敲,系統(tǒng)調(diào)起app的didReceiveRemoteNotification或者didReceiveLocalNotification方法會將點(diǎn)擊的推送內(nèi)容傳遞給這兩個方法,app才能獲得這些數(shù)據(jù)维苔。
另外碰辅,UIApplication也有一個applicationIconBadgeNumber的屬性,該屬性就是代指程序角標(biāo)的介时∶槐觯可以在代碼中直接更改該屬性的值,其效果與遠(yuǎn)程推送的四種情況類似沸柔。強(qiáng)調(diào)一點(diǎn)循衰,當(dāng)程序角標(biāo)為非零時(shí),將UIApplication的applicationIconBadgeNumber屬性設(shè)為零褐澎,會清空通知欄会钝。
綜合上面的結(jié)論,一旦將程序的角標(biāo)從非零置為零工三,就會清空通知欄的所有通知迁酸。如果想清除角標(biāo)但不清空通知欄,有如下方法:
1.發(fā)送一條遠(yuǎn)程推送俭正,推送內(nèi)容只有badge奸鬓,并將badge的值設(shè)為負(fù)數(shù)。此時(shí)程序角標(biāo)會消失但是通知欄的推送消息不清除(此處有待確定)掸读。
2.同樣的方法串远,發(fā)送一條本地推送。
不能通過直接將UIApplication的applicationIconBadgeNumber設(shè)為負(fù)數(shù)的方法解決問題儿惫,實(shí)驗(yàn)證明澡罚,這種做法一樣會清空通知欄。