Core Bluetooth 中iOS應(yīng)用程序的后臺(tái)處理
對(duì)于iOS應(yīng)用程序官觅,知道你的應(yīng)用程序是在前臺(tái)或后臺(tái)運(yùn)行是很重要的。一個(gè)應(yīng)用程序在后臺(tái)比在前臺(tái)必須表現(xiàn)得更不同搔弄,因?yàn)樵趇OS設(shè)備上系統(tǒng)的資源是有限制的日熬。在iOS中關(guān)于多重任務(wù)的全部討論携冤,請(qǐng)看在App Programming Guide for iOS中的App States and Multitasking
默認(rèn)情況下卵皂,很多普遍的Core Bluetooth任務(wù)--在中央端和外設(shè)端兩者中--當(dāng)你的應(yīng)用程序處于后臺(tái)或懸浮狀態(tài)時(shí)都是無(wú)效的秩铆。也就是說(shuō),你可以宣布你的應(yīng)用程序來(lái)支持Core Bluetooth后臺(tái)執(zhí)行模式來(lái)允許你的應(yīng)用程序從懸浮狀態(tài)喚醒來(lái)處理一個(gè)確定的藍(lán)牙相關(guān)的事件灯变。甚至如果你的應(yīng)用程序不需要后臺(tái)進(jìn)程支持的所有范圍殴玛,它仍然可以在重要的事件發(fā)生時(shí)由系統(tǒng)給出一個(gè)警告捅膘。
即使你的應(yīng)用程序支持一個(gè)或兩個(gè)Core Bluetooth后臺(tái)執(zhí)行模式,它也不會(huì)一直運(yùn)行族阅。在有些時(shí)候篓跛,例如膝捞,系統(tǒng)可能需要為處于前臺(tái)的應(yīng)用程序而終止你的應(yīng)用程序來(lái)釋放資源-導(dǎo)致任何活動(dòng)或等待連接丟失坦刀。對(duì)于iOS7,Core Bluetooth支持為中央管理者對(duì)象和外設(shè)管理者對(duì)象保存狀態(tài)信息蔬咬,并在應(yīng)用程序啟動(dòng)時(shí)恢復(fù)狀態(tài)鲤遥。你可以用這個(gè)特征來(lái)支持一個(gè)長(zhǎng)期的活動(dòng)與藍(lán)牙設(shè)備交互。
應(yīng)用程序只處于前臺(tái)時(shí)
對(duì)于大多數(shù)iOS應(yīng)用程序林艘,除非你請(qǐng)求允許執(zhí)行指定后臺(tái)任務(wù)盖奈,你的應(yīng)用程序在進(jìn)入后臺(tái)之后會(huì)很快轉(zhuǎn)變?yōu)閼腋顟B(tài)。當(dāng)在懸浮狀態(tài)下狐援,你的應(yīng)用程序不能執(zhí)行藍(lán)牙相關(guān)任務(wù)钢坦,也不會(huì)知道任何藍(lán)牙相關(guān)的事件直到它在前臺(tái)喚醒。
在中央端啥酱,只處于前臺(tái)的應(yīng)用程序--沒(méi)有宣布支持任何一種Core Bluetooth后臺(tái)執(zhí)行模式--在處于后臺(tái)或懸浮狀態(tài)時(shí)不可以?huà)呙韬桶l(fā)現(xiàn)正在廣播的外設(shè)爹凹。在外設(shè)端,不能夠廣播镶殷,并且任何中央嘗試訪(fǎng)問(wèn)一個(gè)應(yīng)用程序發(fā)布服務(wù)的動(dòng)態(tài)特征值會(huì)接受到一個(gè)錯(cuò)誤禾酱。
根據(jù)用例,這種默認(rèn)的行為可能在很多方面會(huì)影響你的應(yīng)用程序绘趋。作為一個(gè)例子颤陶,想象你正在與一個(gè)你當(dāng)前連接的外設(shè)交互數(shù)據(jù)。現(xiàn)在想象你的應(yīng)用程序進(jìn)入懸浮狀態(tài)(因?yàn)橄菡冢热缱易撸脩?hù)切換到另一個(gè)應(yīng)用程序)。如果當(dāng)你的應(yīng)用程序是懸浮的時(shí)候連接的外設(shè)丟失帽馋,你將意識(shí)不到任何斷開(kāi)連接的事件直到你的應(yīng)用程序在前臺(tái)喚醒闲坎。
利用外設(shè)連接的選項(xiàng)
當(dāng)一個(gè)只允許前臺(tái)模式的應(yīng)用程序處于懸浮狀態(tài)時(shí)所有與藍(lán)牙相關(guān)的發(fā)生事件會(huì)被系統(tǒng)放在隊(duì)列中,然后只有當(dāng)應(yīng)用程序處于再次處于前臺(tái)時(shí)將它們傳遞給應(yīng)用程序并恢復(fù)茬斧。也就是說(shuō)腰懂,Core Bluetooth提供了一個(gè)方式當(dāng)確定的中央角色事件發(fā)生時(shí)來(lái)提醒用戶(hù)。用戶(hù)可以使用這些提醒來(lái)決定是否要根據(jù)一個(gè)特定的事件將應(yīng)用程序帶回前臺(tái)项秉。
你可以利用這些提醒在調(diào)用CBCentralManager
類(lèi)的connectPeripheral:options:
方法來(lái)連接遠(yuǎn)程外設(shè)時(shí)通過(guò)下面外設(shè)連接選項(xiàng)中的一個(gè)绣溜。
-
CBConnectPeripheralOptionNotifyOnConnectionKey
--包含這個(gè)鍵表示如果你想要在連接成功后應(yīng)用程序處于懸浮狀態(tài)時(shí)系統(tǒng)給你的一個(gè)給定的外設(shè)顯示一個(gè)警告。 -
CBConnectPeripheralOptionNotifyOnDisconnectionKey
--包含這個(gè)鍵表示如果你想要在斷開(kāi)連接應(yīng)用程序處于后臺(tái)時(shí)系統(tǒng)給你的一個(gè)給定的外設(shè)顯示一個(gè)斷開(kāi)連接的警告娄蔼。 -
CBConnectPeripheralOptionNotifyOnNotificationKey
--包含這個(gè)鍵表示如果你想要在應(yīng)用程序處于懸浮狀態(tài)時(shí)系統(tǒng)從給定的外設(shè)接受到通知時(shí)顯示一個(gè)警告怖喻。
關(guān)于外設(shè)連接選項(xiàng)的更多信息底哗,請(qǐng)看Peripheral Connection Options常量,詳細(xì)在CBCentralManager Class Reference中锚沸。
Core Bluetooth后臺(tái)執(zhí)行模式
如果你的應(yīng)用程序需要在后臺(tái)運(yùn)行來(lái)執(zhí)行確定的藍(lán)牙相關(guān)任務(wù)跋选,必須在Information property list(Info.plist)
文件中指定它支持Core Bluetooth后臺(tái)執(zhí)行模式。當(dāng)你的應(yīng)用程序制定了這個(gè)哗蜈,系統(tǒng)從懸浮狀態(tài)喚醒來(lái)允許它執(zhí)行藍(lán)牙相關(guān)任務(wù)前标,這個(gè)支持對(duì)于應(yīng)用程序在與藍(lán)牙低功耗設(shè)備交互時(shí)在有規(guī)律的間隔時(shí)間里傳遞數(shù)據(jù)是很重要的,比如心率監(jiān)測(cè)器距潘。
有兩個(gè)應(yīng)用程序可以指定的Core Bluetooth后臺(tái)執(zhí)行模式--一個(gè)是為應(yīng)用程序?qū)崿F(xiàn)中央角色炼列,另一個(gè)是為應(yīng)用程序事件外設(shè)角色。如果你的應(yīng)用程序?qū)崿F(xiàn)了它們兩個(gè)角色音比,可以同時(shí)指定它支持兩個(gè)后臺(tái)執(zhí)行模式贷币。這個(gè)Core Bluetooth后臺(tái)執(zhí)行模式是通過(guò)在你的Info.plist
文件中添加UIBackgroundModes
鍵來(lái)添加苛萎,并且設(shè)置這個(gè)鍵的值到一個(gè)數(shù)組容器中如下面的字符串:
-
bluetooth-central
--使用Core Bluetooth框架與藍(lán)牙低功耗外設(shè)交互的應(yīng)用程序嗜侮。 -
bluetooth-peripheral
--使用Core Bluetooth框架分享數(shù)據(jù)的應(yīng)用程序沮翔。
注意:在Xcode中這個(gè)屬性列表默認(rèn)為很多鍵顯示人類(lèi)可讀的字符串來(lái)替代一個(gè)真實(shí)的鍵名。在
Info.plist
文件中顯示一個(gè)真實(shí)的鍵名骚亿,在編輯窗口控制點(diǎn)擊任何一個(gè)鍵并在上下文窗口顯示鍵值對(duì)的條目已亥。
關(guān)于如何配置你的Info.plist
文件中的內(nèi)容更多信息,請(qǐng)看Property List Editor Help循未。
藍(lán)牙-中央后臺(tái)執(zhí)行模式
當(dāng)一個(gè)應(yīng)用程序?qū)崿F(xiàn)了中央角色包括在它的Info.plist
文件中添加了UIBackgroundModes
鍵和對(duì)應(yīng)的bluetooth-central
值陷猫,這個(gè)Core Bluetooth框架會(huì)允許你的 應(yīng)用程序在后臺(tái)運(yùn)行執(zhí)行確定的藍(lán)牙相關(guān)任務(wù)。當(dāng)你的應(yīng)用程序處于后臺(tái)時(shí)仍然可以發(fā)現(xiàn)和連接外設(shè)的妖,并探索和與外設(shè)數(shù)據(jù)交互绣檬。另外,當(dāng)任何CBCentralManagerDelegate
或CBPeripheralDelegate
代理方法被調(diào)用時(shí)系統(tǒng)會(huì)喚醒你的應(yīng)用程序嫂粟,允許你的應(yīng)用程序來(lái)處理重要的中央角色事件娇未,例如當(dāng)連接被建立或減弱時(shí),當(dāng)一個(gè)外設(shè)發(fā)送更新特征值時(shí)星虹,當(dāng)中央管理者狀態(tài)改變時(shí)零抬。
雖然你可以在你的應(yīng)用程序處于后臺(tái)時(shí)執(zhí)行很多藍(lán)牙相關(guān)任務(wù),但請(qǐng)記住你的應(yīng)用程序處于后臺(tái)時(shí)的掃描外設(shè)操作是與你的應(yīng)用程序處于前臺(tái)時(shí)是不同的宽涌。特別的平夜,當(dāng)你的應(yīng)用程序在后臺(tái)正在掃描設(shè)備時(shí):
-
CBCentralManagerScanOptionAllowDuplicatiesKey
鍵選項(xiàng)將被忽視,并且多個(gè)發(fā)現(xiàn)正在廣播的外設(shè)會(huì)合并成單個(gè)的發(fā)現(xiàn)事件卸亮。 - 如果所有的應(yīng)用程序在后臺(tái)時(shí)正在掃描外設(shè)忽妒,你的中央設(shè)備掃描正在廣播包的時(shí)間間隔會(huì)增多。因此,它可能需要更長(zhǎng)的時(shí)間來(lái)發(fā)現(xiàn)正在廣播的外設(shè)段直。
這些改變會(huì)有助于在你的iOS設(shè)備上最小化無(wú)線(xiàn)的使用和提供電池的壽命吃溅。
藍(lán)牙-外設(shè)后臺(tái)執(zhí)行模式
為了在后臺(tái)執(zhí)行確定的外設(shè)角色任務(wù),你必須在你的Info.plist
文件中添加UIBackgroundModes
鍵對(duì)應(yīng)的值bluetooth-peripheral
鸯檬。當(dāng)在應(yīng)用程序的Info.plist
文件中包含這對(duì)鍵值時(shí)决侈,系統(tǒng)會(huì)喚醒你的應(yīng)用程序來(lái)處理讀,寫(xiě)和訂閱事件喧务。
除了允許你的應(yīng)用程序被喚醒來(lái)處理來(lái)自連接的中央的讀赖歌,寫(xiě)和訂閱請(qǐng)求之外,Core Bluetooth
框架還允許你的應(yīng)用程序在處于后臺(tái)時(shí)發(fā)出廣播蹂楣。也就是說(shuō)俏站,你需要意識(shí)到當(dāng)你的應(yīng)用程序處于后臺(tái)操作廣播時(shí)是與你的應(yīng)用程序處于前臺(tái)模式時(shí)是不同的讯蒲。特別的痊土,當(dāng)你的應(yīng)用程序在后臺(tái)廣播時(shí):
-
CBAdvertisementDataLocalNameKey
廣播鍵是被忽略的,設(shè)備的本地名不會(huì)被廣播墨林。 - 所有服務(wù)的UUIDs包含
CBAdvertisementDataServiceUUIDsKey
廣播鍵對(duì)應(yīng)的值會(huì)被一個(gè)特定的溢出區(qū)域代替赁酝。它們只能被指定掃描它們的iOS設(shè)備發(fā)現(xiàn)。 - 如果所有的應(yīng)用程序在后臺(tái)時(shí)廣播旭等,你的外設(shè)發(fā)送廣播包的頻率會(huì)減少酌呆。
明智地使用后臺(tái)執(zhí)行模式
雖然在一個(gè)特殊使用情況下指定你的應(yīng)用程序支持一個(gè)或兩個(gè)Core Bluetooth后臺(tái)執(zhí)行模式可能是需要的,但你應(yīng)該負(fù)責(zé)任地執(zhí)行后臺(tái)程序搔耕。因?yàn)閳?zhí)行大量的藍(lán)牙相關(guān)的任務(wù)需要iOS設(shè)備的無(wú)線(xiàn)使用是活躍的-但相反無(wú)線(xiàn)的使用不利于iOS設(shè)備的電池壽命--盡量最小化處于后臺(tái)工作的次數(shù)隙袁。為任何藍(lán)牙相關(guān)的事件喚醒應(yīng)用程序應(yīng)該盡可能快的處理它們并返回,以至于應(yīng)用程序可以再次被掛起弃榨。
任何應(yīng)用程序制定支持Core Bluetooth后臺(tái)執(zhí)行模式必須遵守下面幾個(gè)基本的指導(dǎo)方針:
- 應(yīng)用程序應(yīng)該有基本的會(huì)話(huà)或提供接口來(lái)允許用戶(hù)來(lái)決定什么時(shí)候來(lái)開(kāi)始和停止處理藍(lán)牙相關(guān)事件菩收。
- 在被喚醒后,應(yīng)用程序有十秒鐘的時(shí)間來(lái)完成任務(wù)鲸睛。理想狀態(tài)下娜饵,它應(yīng)該盡可能快的完成任務(wù)并允許它自己被再次掛起。應(yīng)用程序在后臺(tái)花費(fèi)太多時(shí)間運(yùn)行會(huì)被系統(tǒng)限制或殺死官辈。
- 應(yīng)用程序不應(yīng)該有機(jī)會(huì)被喚醒來(lái)執(zhí)行一個(gè)不相關(guān)的外來(lái)任務(wù)因?yàn)閼?yīng)用程序是由系統(tǒng)喚醒的箱舞。
關(guān)于你的應(yīng)用程序應(yīng)該如何在后臺(tái)狀態(tài)下表現(xiàn)的更多信息,請(qǐng)看做一個(gè)負(fù)責(zé)任的后臺(tái)應(yīng)用程序在App Programming Guide for iOS拳亿。
在后臺(tái)執(zhí)行長(zhǎng)期的動(dòng)作
有些應(yīng)用程序可能需要使用Core Bluetooth框架在后臺(tái)執(zhí)行長(zhǎng)期的動(dòng)作晴股。作為一個(gè)例子,想象你正在開(kāi)發(fā)一個(gè)家庭安全的應(yīng)用程序?yàn)閕OS設(shè)備與門(mén)鎖交互(裝備有藍(lán)牙低功耗技術(shù))肺魁。在用戶(hù)離開(kāi)家的時(shí)候這個(gè)應(yīng)用程序自動(dòng)將門(mén)鎖鎖住并在用戶(hù)返回家的時(shí)候?qū)㈤T(mén)鎖打開(kāi)--所有的過(guò)程都是在后臺(tái)執(zhí)行电湘。在用戶(hù)離開(kāi)家時(shí),應(yīng)用程序最終可能離開(kāi)鎖的范圍,造成與鎖失去連接胡桨。在這一點(diǎn)上官帘,可以簡(jiǎn)單地調(diào)用CBCentralManager
類(lèi)的connectPeripheral:options:
方法,因?yàn)檫B接請(qǐng)求不會(huì)超時(shí)昧谊,iOS設(shè)備會(huì)在用戶(hù)返回家的時(shí)候重連上刽虹。
現(xiàn)在想象離開(kāi)家?guī)滋臁H绻谟脩?hù)離開(kāi)的時(shí)候應(yīng)用程序被系統(tǒng)終止呢诬,這個(gè)應(yīng)用程序?qū)⒉豢赡茉谟脩?hù)返回家的時(shí)候重連上鎖涌哲,用戶(hù)也不可能打開(kāi)門(mén)鎖。像這樣的應(yīng)用程序尚镰,關(guān)鍵是能夠繼續(xù)使用Core Bluetooth來(lái)執(zhí)行長(zhǎng)期動(dòng)作阀圾,就像監(jiān)測(cè)活動(dòng)和掛起的連接。
狀態(tài)保存和恢復(fù)
因?yàn)闋顟B(tài)的保存和恢復(fù)是建立在Core Bluetooth中狗唉,你的應(yīng)用程序能夠選擇這個(gè)特征讓系統(tǒng)保存你的應(yīng)用程序的中央管理者和外設(shè)管理者的狀態(tài)并在它們的行為上繼續(xù)執(zhí)行藍(lán)牙相關(guān)任務(wù)初烘,甚至當(dāng)你的應(yīng)用程序不再運(yùn)行了。當(dāng)其中一個(gè)任務(wù)完成了分俯,系統(tǒng)會(huì)重啟你的應(yīng)用程序進(jìn)入后臺(tái)肾筐,并讓你的應(yīng)用程序有機(jī)會(huì)恢復(fù)它們的狀態(tài)和處理恰當(dāng)?shù)氖录T谏厦婷枋龅募彝グ踩珣?yīng)用程序的情況下缸剪,系統(tǒng)會(huì)監(jiān)測(cè)連接請(qǐng)求,并在用戶(hù)返回家完成連接請(qǐng)求時(shí)重啟應(yīng)用程序處理centralManager:didConnectPeripheral:
代理的回調(diào)吗铐。
Core Bluetooth支持實(shí)現(xiàn)中央角色,外設(shè)角色或兩者都有的應(yīng)用程序的狀態(tài)保存和恢復(fù)杏节。當(dāng)你的應(yīng)用程序?qū)崿F(xiàn)了中央角色并添加支持狀態(tài)保存和恢復(fù)唬渗,在系統(tǒng)為釋放內(nèi)存終止你的應(yīng)用程序時(shí)會(huì)保存你的中央管理者的狀態(tài)(如果你的應(yīng)用程序有多個(gè)中央管理者,你可以選擇讓你的系統(tǒng)保存其中一個(gè))奋渔。特別地镊逝,對(duì)于一個(gè)給定的CBCentralManager
對(duì)象,系統(tǒng)會(huì)跟蹤:
- 中央管理者已經(jīng)掃描到服務(wù)(當(dāng)開(kāi)始掃描時(shí)制定掃描選項(xiàng))
- 中央管理者已經(jīng)嘗試連接或已經(jīng)連接過(guò)的外設(shè)
- 中央管理者已經(jīng)訂閱了特征
實(shí)現(xiàn)了外設(shè)角色的應(yīng)用程序同樣可以利用狀態(tài)保存和恢復(fù)卒稳。對(duì)于CBPeripheralManager
對(duì)象蹋半,系統(tǒng)會(huì)跟蹤:
- 外設(shè)管理者已經(jīng)廣播了數(shù)據(jù)
- 外設(shè)管理者已經(jīng)給設(shè)備數(shù)據(jù)庫(kù)發(fā)布了服務(wù)和特征
- 中央已經(jīng)訂閱了你的特征值
當(dāng)你的應(yīng)用程序被系統(tǒng)在重啟進(jìn)入后臺(tái)(因?yàn)槟愕膽?yīng)用程序已經(jīng)掃描發(fā)現(xiàn)的外設(shè)),你可以重新實(shí)例化你的應(yīng)用程序的中央和外設(shè)管理者并恢復(fù)它們的狀態(tài)。接下來(lái)的部分詳細(xì)地描述在你的應(yīng)用程序上怎樣使用狀態(tài)保存和恢復(fù)充坑。
為狀態(tài)保存和恢復(fù)添加支持
在Core Bluetooth中狀態(tài)保存和恢復(fù)是可選的特征并對(duì)你的應(yīng)用程序工作有必要的幫助减江。你可以通過(guò)下面的步驟在你的應(yīng)用程序上的這個(gè)特征添加支持:
- (必須)當(dāng)你給中央和外設(shè)管理者對(duì)象分配內(nèi)存和初始化時(shí)選擇狀態(tài)保存和恢復(fù)。這一步在Opt in to State Preservation and Restoration有描述捻爷。
- (必須)在你的應(yīng)用程序被系統(tǒng)重啟時(shí)重新初始化任何中央或外設(shè)管理者對(duì)象辈灼。這一步在Reinstantiate Your Central and Peripheral Managers有描述。
- (必須)實(shí)現(xiàn)恰當(dāng)?shù)幕謴?fù)代理方法也榄。這一步在Implement the Appropriate Restoration Delegate Method有描述巡莹。
4.(可選)更新你的中央和外設(shè)管理者的初始化過(guò)程司志。這一步在Update Your Initialization Process有描述。
選擇狀態(tài)保存和恢復(fù)
為了選擇狀態(tài)保存和恢復(fù)特征降宅,當(dāng)你分配內(nèi)存和初始化一個(gè)中央或外設(shè)管理者時(shí)簡(jiǎn)單地提供一個(gè)唯一的恢復(fù)標(biāo)識(shí)符骂远。一個(gè)恢復(fù)標(biāo)識(shí)符是一個(gè)字符串,標(biāo)識(shí)著你的應(yīng)用程序和Core Bluetooth中的中央或外設(shè)管理者腰根。這個(gè)字符串的值只對(duì)你的代碼有重要意義激才,但是這個(gè)字符串的存在告訴了Core Bluetooth它需要保存標(biāo)識(shí)對(duì)象的狀態(tài)。Core Bluetooth只保存有一個(gè)恢復(fù)標(biāo)識(shí)符的對(duì)象狀態(tài)额嘿。
例如瘸恼,在一個(gè)只使用一個(gè)CBCentralManager
對(duì)象的實(shí)例來(lái)實(shí)現(xiàn)中央角色的應(yīng)用程序上選擇狀態(tài)保存和恢復(fù),在你給它分配內(nèi)存和初始化時(shí)指定CBCentralManagerOptionRestoreIdentifierKey
初始化選項(xiàng)并給中央管理者提供一個(gè)標(biāo)識(shí)符册养。
myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionRestoreIdentifierKey: @"myCentralManagerIdentifier"}];
雖然上面的例子不能闡述這些东帅,你可以在一個(gè)應(yīng)用程序選擇狀態(tài)保存和恢復(fù)使用外設(shè)管理對(duì)象在相似的方式:在你分配內(nèi)存和初始化任何外設(shè)管理者對(duì)象時(shí)指定CBPeripheralManagerOptionRestoreIdentifierKey
初始化選項(xiàng)并提供一個(gè)恢復(fù)標(biāo)識(shí)符。
注意:因?yàn)閼?yīng)用程序可以有多個(gè)
CBCentralManager
和CBPeripheralManager
對(duì)象的實(shí)例球拦,確保任何恢復(fù)標(biāo)識(shí)符是唯一的靠闭,以至于系統(tǒng)能夠從其它對(duì)象中區(qū)分一個(gè)中央(或外設(shè))管理者
重新初始化你的中央和外設(shè)管理者
當(dāng)你的應(yīng)用程序被系統(tǒng)重啟進(jìn)入后臺(tái)時(shí),你需要做的第一件事是使用相同的恢復(fù)標(biāo)識(shí)符來(lái)重新實(shí)例化恰當(dāng)?shù)闹醒牒屯庠O(shè)管理者當(dāng)它們已經(jīng)有過(guò)被第一次創(chuàng)建了刘莹。如果你的應(yīng)用程序只有一個(gè)中央或外設(shè)管理者阎毅,并且這個(gè)管理者存在于你的應(yīng)用程序的生命周期里焚刚,你不需要為這一步做更多的事点弯。
如果你的應(yīng)用程序使用了超過(guò)一個(gè)的中央或外設(shè)管理者,活著如果使用一個(gè)管理者不在你的應(yīng)用程序的生命周期范圍內(nèi)矿咕,你的應(yīng)用程序需要知道當(dāng)被系統(tǒng)重啟時(shí)哪一個(gè)管理者被重新初始化抢肛。你可以訪(fǎng)問(wèn)所有恢復(fù)標(biāo)識(shí)符的一個(gè)列表為系統(tǒng)在它被終止時(shí)保存的管理者對(duì)象,通過(guò)使用恰當(dāng)?shù)膯?dòng)選項(xiàng)鍵(UIApplicationLaunchOptionsBluetoothCentralsKey
或UIApplicationLaunchOptionsBluetoothPeripheralsKey
)在實(shí)現(xiàn)你的應(yīng)用程序代理的application:didFinishLaunchingWithOptions:
方法中碳柱。
例如捡絮,當(dāng)你的應(yīng)用程序被系統(tǒng)重啟,你可以獲得系統(tǒng)為你的應(yīng)用程序保存的中央管理者對(duì)象的恢復(fù)標(biāo)識(shí)符莲镣。就像:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSArray *centralManagerIdentifiers = launchOptions[UIApplicationLaunchOptionsBluetoothCentralsKey];
...
}
在你有了這個(gè)恢復(fù)標(biāo)識(shí)符列表后福稳,通過(guò)它們簡(jiǎn)單的循環(huán)來(lái)重新初始化恰當(dāng)?shù)闹醒牍芾碚邔?duì)象。
注意:當(dāng)你的應(yīng)用程序重啟時(shí)瑞侮,系統(tǒng)提供的恢復(fù)標(biāo)識(shí)符只是為了執(zhí)行一些藍(lán)牙相關(guān)任務(wù)的中央和外設(shè)管理者(當(dāng)應(yīng)用程序不再運(yùn)行時(shí)),這些啟動(dòng)選項(xiàng)鍵在UIApplicationDelegate Protocol Reference中有詳細(xì)的描述的圆。
實(shí)現(xiàn)恰當(dāng)?shù)幕謴?fù)代理方法
當(dāng)你在你的應(yīng)用程序里已經(jīng)重新實(shí)例化了恰當(dāng)?shù)闹醒牒屯庠O(shè)管理者后,通過(guò)藍(lán)牙系統(tǒng)的狀態(tài)同步它們的狀態(tài)來(lái)恢復(fù)它們半火。為了給你的應(yīng)用程序帶來(lái)與系統(tǒng)已經(jīng)處理它的表現(xiàn)的速度(在它沒(méi)有運(yùn)行的時(shí)候)越妈,你必須實(shí)現(xiàn)恰當(dāng)?shù)幕謴?fù)代理方法。對(duì)于中央管理者钮糖,實(shí)現(xiàn)centralManager:willRestoreState:
代理方法梅掠;對(duì)于外設(shè)管理者,實(shí)現(xiàn)peripheralManager:willRestoreState:
代理方法。
重點(diǎn):對(duì)于應(yīng)用程序選擇Core Bluetooth的狀態(tài)保存和恢復(fù)特征阎抒,當(dāng)你的應(yīng)用程序重啟到后臺(tái)來(lái)完成一些藍(lán)牙相關(guān)任務(wù)時(shí)第一方法(
centralManager:willRestoreState:
和peripheralManager:willRestoreState:
)會(huì)被調(diào)用酪我。對(duì)于沒(méi)有選擇保存狀態(tài)的應(yīng)用程序(或者如果沒(méi)有恢復(fù)啟動(dòng)),centralManagerDidUpdateState:
和peripheralManagerDidUpdateState:
代理方法會(huì)被第一個(gè)調(diào)用。
在以上的兩個(gè)代理方法中且叁,最后一個(gè)參數(shù)是一個(gè)字典祭示,包含在應(yīng)用程序被終結(jié)時(shí)保存了狀態(tài)的管理者的信息。對(duì)于有效字典鍵的列表谴古,請(qǐng)看在CBCentralManagerDelegate Protocol Reference中的Central Manager State Restoration Options常量和在CBPeripheralManagerDelegate Protocol Reference中的Peripheral_Manager_State_Restoration_Options常量质涛。
為了恢復(fù)CBCentralManager
對(duì)象的狀態(tài),使用在centralManager:willRestoreState:
代理方法中提供的字典的鍵掰担。作為一個(gè)例子汇陆,如果你的中央管理者對(duì)象已經(jīng)活躍或等待連接的應(yīng)用程序被終止,系統(tǒng)會(huì)繼續(xù)監(jiān)視它們?cè)谀愕膽?yīng)用程序的行為带饱。如下所示毡代,你可以使用CBCentralManagerRestoredStatePeripheralKey
字典鍵來(lái)獲得所有中央管理者已經(jīng)連接過(guò)或嘗試連接的外設(shè)(使用CBPeripheral
對(duì)象表示)的列表。
- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)state {
NSArray *peripherals = state[CBCentralManagerRestoredStatePeripheralsKey];
...
}
在上面的例子中你用這些恢復(fù)外設(shè)的列表做什么依賴(lài)與實(shí)際使用情況勺疼。例如教寂,如果你的應(yīng)用程序獲得了中央管理者發(fā)現(xiàn)的外設(shè)列表,你可能想要恢復(fù)外設(shè)添加到列表來(lái)保持引用它們执庐。正如在Connecting to a Peripheral Device After You've Discovered It中的描述酪耕,設(shè)置一個(gè)外設(shè)的代理確保能接受到它恰當(dāng)?shù)幕卣{(diào)。
你可以用相似的方式通過(guò)使用peripheralManager:willRestoreState:
代理方法中提供的字典使用鍵來(lái)恢復(fù)CBPeripheralManager
對(duì)象的狀態(tài)轨淌。
更新你的初始化過(guò)程
在你已經(jīng)實(shí)現(xiàn)了以上三個(gè)必須的步驟后迂烁,你可能想要看看更新你的中央和外設(shè)管理者的初始化過(guò)程。雖然這是個(gè)可選步驟递鹉,它也是很重要的以確保你的應(yīng)用程序流暢的運(yùn)行盟步。例如,你的應(yīng)用程序可能在它與連接的外設(shè)探索數(shù)據(jù)過(guò)程中被終止躏结,當(dāng)你的應(yīng)用程序恢復(fù)了這個(gè)外設(shè)却盘,它不知道離它被終止到發(fā)現(xiàn)的過(guò)程有多久。你將想要確保從你離開(kāi)發(fā)現(xiàn)過(guò)程到重新開(kāi)始媳拴。
例如黄橘,當(dāng)在centralManagerDidUpdateState:
代理方法中初始化你的應(yīng)用程序,你可以發(fā)現(xiàn)你會(huì)成功地發(fā)現(xiàn)一個(gè)指定服務(wù)的恢復(fù)的外設(shè)(在你的應(yīng)用程序被終止前),就像:
NSUInteger serviceUUIDIndex = [peripheral.services indexOfObjectPassingTest:^BOOL(CBService *obj, NSUInteger index, BOOL *stop) {
return [obj.UUID isEqual:myServiceUUIDString];
}];
if (serviceUUIDIndex == NSNotFound) {
[peripheral discoverServices:@[myServiceUUIDString]];
...
}
在上面的例子顯示禀挫,如果系統(tǒng)在完成發(fā)現(xiàn)服務(wù)之前終止了你的應(yīng)用程序旬陡,通過(guò)調(diào)用discoverServices:
方法開(kāi)始探索恢復(fù)的外設(shè)數(shù)據(jù)。如果你的應(yīng)用程序成功地發(fā)現(xiàn)了服務(wù)语婴,你可以檢查看看發(fā)現(xiàn)服務(wù)的恰當(dāng)?shù)奶卣?和你已經(jīng)訂閱了它們)描孟。在這個(gè)方式上通過(guò)更新你的初始化過(guò)程驶睦,你將確保你在正確的時(shí)間調(diào)用正確的方法。
--翻譯的文檔地址: Core Bluetooth Background Processing for iOS Apps