每個(gè) Home 都有一個(gè) HomeKit 數(shù)據(jù)庫(kù)。如下圖所示,HomeKit 數(shù)據(jù)庫(kù)會(huì)安全地和 home 授權(quán)的用戶的 iOS 設(shè)備以及潛在的客人的 iOS 設(shè)備進(jìn)行同步。為了給用戶展示當(dāng)前最新的數(shù)據(jù),你的應(yīng)用需要觀察 HomeKit 數(shù)據(jù)庫(kù)的變化。
HomKit 使用代理設(shè)計(jì)模式(delegation design pattern)來通知應(yīng)用程序 HomeKit 對(duì)象的改變。一般來講,如果你的應(yīng)用程序調(diào)用了一個(gè)帶有完成處理參數(shù)的 HomeKit 方法,并且這個(gè)方法被成功調(diào)用了,那么相關(guān)聯(lián)的代理消息就會(huì)被發(fā)送給其他 HomeKit 應(yīng)用,無論這些應(yīng)用是安裝在同一臺(tái) iOS 設(shè)備上還是遠(yuǎn)程 iOS 設(shè)備上。這些應(yīng)用甚至可以運(yùn)行在客人的 iOS 設(shè)備上。如果你的應(yīng)用發(fā)起了數(shù)據(jù)改變,但是代理消息并沒有發(fā)送到你的應(yīng)用,那么添加代碼到完成處理方法和相關(guān)聯(lián)的代理方法中來刷新數(shù)據(jù)和更新視圖就成為必須了。如果 home 布局發(fā)生了顯著變化,那么就重新加載關(guān)于這個(gè) home 的所有信息。在完成程序處理的情況下,請(qǐng)?jiān)诟聭?yīng)用之前檢查那個(gè)方法是否成功。Homkit 也會(huì)調(diào)用代理方法來通知你的應(yīng)用程序 home 網(wǎng)絡(luò)狀態(tài)的改變。
例如,下圖演示了使用代理方法的過程:響應(yīng)用戶的操作,你的應(yīng)用程序調(diào)用了 addRoomWithName:completionHandler:方法,并且沒有錯(cuò)誤發(fā)生,完成處理程序應(yīng)當(dāng)更新 home 的所有視圖。如果成功了,homeKit 將會(huì)發(fā)送 home:didAddRoom:消息給其他應(yīng)用中 homes 的代理。因此,你實(shí)現(xiàn)的這個(gè) home:didAddRoom:方法也應(yīng)該更新 home 的所有視圖。
應(yīng)用程序只有在前臺(tái)運(yùn)行的時(shí)候才能接受代理消息。當(dāng)你的應(yīng)用在后臺(tái)時(shí),HomeKit 數(shù)據(jù)庫(kù)的改變并不會(huì)成批處理。也就是說,如果你的應(yīng)用在后臺(tái),當(dāng)其他的應(yīng)用成功地添加一個(gè) room 到 home 中的時(shí)候,你的應(yīng)用程序并不會(huì)接收到 home:didAddRoom: 消息。當(dāng)你的應(yīng)用程序到前臺(tái)運(yùn)行時(shí),你的應(yīng)用程序?qū)?huì)接收到 homeManagerDidUpdateHomes:消息,這個(gè)消息是表示你的應(yīng)用程序要重新加載所有的數(shù)據(jù)。
設(shè)置 home manager 的代理并且實(shí)現(xiàn)HMHomeManagerDelegate協(xié)議,當(dāng) primary home 或者 home 集合發(fā)生改變時(shí),可以接收代理消息。
所有的應(yīng)用都需要實(shí)現(xiàn) homeManagerDidUpdateHomes:方法,這個(gè)方法在完成最初獲取 homes 之后被調(diào)用。對(duì)新建的 home manager 來說,在這個(gè)方法被調(diào)用之前,primaryHome 屬性的值是 nil,homes 數(shù)組是空的數(shù)組。當(dāng)應(yīng)用程序開始在前臺(tái)運(yùn)行時(shí)也會(huì)調(diào)用 homeManagerDidUpdateHomes: 方法,當(dāng)其在后臺(tái)運(yùn)行時(shí)數(shù)據(jù)發(fā)生改變。該 homeManagerDidUpdateHomes:方法會(huì)重新加載與 homes 相關(guān)聯(lián)的所有數(shù)據(jù)。
1.在你的類接口中添加 HMHomeManagerDelegate 代理和 homeManager 屬性。代碼如下:
@interface AppDelegate () @property (strong, nonatomic) HMHomeManager *homeManager;
@end
2.創(chuàng)建 home manager 對(duì)象并設(shè)置其代理
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.homeManager = [[HMHomeManager alloc] init];
self.homeManager.delegate = self;
return YES;
}
3.實(shí)現(xiàn) homes 發(fā)生改變時(shí)調(diào)用的代理方法。例如:如果多個(gè)視圖控制器展示了 homes 相關(guān)信息,你可以發(fā)布一個(gè)更改通知去更新所有視圖。
- (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager {
// Send a notification to the other objects
[[NSNotificationCenter defaultCenter]
postNotificationName:@"UpdateHomesNotification"
object:self];
}
- (void)homeManagerDidUpdatePrimaryHome:(HMHomeManager
*)manager {
// Send a notification to the other objects
[[NSNotificationCenter defaultCenter]
postNotificationName:@"UpdatePrimaryHomeNotification"
object:self];
}
視圖控制器注冊(cè)更改通知并且執(zhí)行適當(dāng)?shù)牟僮鳌?/p>
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateHomes:)
name:@"UpdateHomesNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updatePrimaryHome:)
name:@"UpdatePrimaryHomeNotification" object:nil];
展示 home 信息的視圖控制器應(yīng)該成為 home 對(duì)象的代理,并且當(dāng) home 發(fā)生改變時(shí)更新視圖控制器的視圖。
觀察特定 home 對(duì)象的改變
1.在類接口中添加 home 代理協(xié)議。
@interface HomeViewController () @end
2.設(shè)置配件代理
home.delegate = self;
3.實(shí)現(xiàn)HMHomeDelegate協(xié)議
例如:實(shí)現(xiàn) home:didAddAccessory:和 home:didRemoveAccessory: 方法來更新展示配件的視圖。用 HMAccessory 類的 room 屬性可以獲得配件所屬的 room。(對(duì)配件來說,默認(rèn)的 room 是 roomForEntireHome 這個(gè)方法的返回值。)
Bridge Note:當(dāng)你為 home 添加橋接口時(shí),橋接口底層的配件會(huì)自動(dòng)被添加到 home 中。你的代理會(huì)接收到橋接口后每個(gè)配件的 home:didAddAccessory:消息,但是你的代理不會(huì)接收到橋接口的 home:didAddAccessory:消息。
配件的狀態(tài)可以在任何時(shí)間發(fā)生變化。配件可能不能被獲得,可以被移除,或者被關(guān)閉。請(qǐng)更新用戶界面以反映配件狀態(tài)的更改,尤其是如果你的 App 允許用戶控制配件時(shí)。
這以下步驟中,我們假設(shè)你已經(jīng)從 HomeKit 數(shù)據(jù)庫(kù)中檢索到了配件對(duì)象,正如 Getting the Accessories in a Room中描述的那樣。
在類接口中添加配件代理協(xié)議。
@interface AccessoryViewController ()
@end
設(shè)置配件的代理
accessory.delegate = self;
實(shí)現(xiàn)HMAccessoryDelegate協(xié)議
比如,執(zhí)行 accessoryDidUpdateReachability:方法以啟用或者禁用配件控制。
- (void)accessoryDidUpdateReachability:(HMAccessory *)accessory {
if (accessory.reachable == YES) {
// Can communicate with the accessory
} else {
// The accessory is out of range, turned off, etc
}
}
如果你展示了配件的服務(wù)狀態(tài)和特性,那么請(qǐng)執(zhí)行以下代理方法來相應(yīng)地更新其視圖:
accessory:service:didUpdateValueForCharacteristic:
想了解配件的服務(wù),請(qǐng)參閱Accessing Services and Their Characteristics.
更多建議: