(一)創(chuàng)建Home布局
1> 允許用戶創(chuàng)建一個或多個Home布局,每個Home代表一個有網(wǎng)絡(luò)設(shè)備的住所.
2> 用戶擁有Home的數(shù)據(jù)并可通過自己的任何一臺iOS設(shè)備進行訪問。
3> 用戶也可以和客戶共享一個Home,但是客戶的權(quán)限會有更多限制。
4> 被指定為primary home的home默認(rèn)是Siri指令的對象,并且不能指定home。
5> 每個Home一般有多個room,并且每個room一般會有多個智能配件。
6> 在home中,每個房間是獨立的room,并具有一個有意義的名字,例如“臥室”或者“廚房”,這些名字可以在Siri 命令中使用。
7> 一個accessory代表實際家庭中的自動化設(shè)備,例如車庫開門器。
8> 一個sevice是accessory提供的?種實際服務(wù),例如打開或者關(guān)閉車庫,或者車庫上的燈。
9> 如果你的app 緩存了home布局的信息,那么當(dāng)其布局發(fā)聲改變的時候,app就需要更新這些信息。
10> 使用HMHomeManager對象可以從HomeKit數(shù)據(jù)庫獲取HMHome和其他相關(guān)的對象
11> 本章描述的API獲取對象后,你應(yīng)該通過代理回調(diào)函數(shù)保持獲取對象和HomeKit數(shù)據(jù)庫同步,具體描述請參看“Observing HomeKit Database Changes
創(chuàng)建Home Manager 對象
使用HMHomeManager對象的訪問home、room、配件、服務(wù)以及其他HomeKit對象。
在創(chuàng)建家庭對象管理器(home manager)之后,直接設(shè)置它的代理,以便獲取到這些對象之后及時的通知到你。
self.homeManager = [[HMHomeManager alloc] init];
self.homeManager.delegate = self;
當(dāng)你創(chuàng)建一個home manager對象時,HomeKit就開始從HomeKit數(shù)據(jù)庫獲取這些homes和相關(guān)對象,例如room和accessory對象。
當(dāng)HomeKit正在獲取那些對象時,home manager 的primaryHome屬性是nil,并且homes屬性是個空數(shù)組。
你的app應(yīng)該處理用戶還沒有完成創(chuàng)建home的情況,但是app應(yīng)該等待直到HomeKit完成初始化。當(dāng)獲取對象完成之后,HomeKit 會發(fā)送homeManagerDidUpdateHomes:消息給home manager的代理。
當(dāng)app進入前臺或者在后臺Home manager屬性發(fā)生改變時,這個homeManagerDidUpdateHomes:方法就會被調(diào)用,詳情請參閱“Observing Changes to the Collection of Homes。
獲取Primary Home和 Homes集合
獲取 展示數(shù)據(jù)
- (一) 通過home manager的primaryHome屬性,可以得到primary home,代碼如下:
HMHome *home = self.homeManager.primaryHome;
- (二) 使用home manager的homes屬性可以得到用戶的所有home的集合;例如自家主要居所、度假別墅以及辦公室。每個home都對應(yīng)一個獨立的home對象。
HMHome *home;
for (home in self.homeManager.homes ){
... ...
}
- (三) 獲取 Home中的所有room, 在一個home中,rooms屬性定義accessories的物理位置。用home的rooms屬性可以枚舉home中的所room。
HMHome *home = self.homeManager.primaryHome;
HMRome *room;
for(room in home.rooms){
... ...
}
- (四) 獲取Room 中的Accessories,Accessories 數(shù)組屬于home,但是被指定給了home中的room。假如用戶沒有給一個accessory指定room,那么這個accessories被指定一個默認(rèn)的room ,這個room是roomForEntireHome方法的返回值。用room的accessories屬性可以枚舉room中所有的accessory。代碼如下:
HMAccessory *accessory;
for(accessory in room.accessories){
... ...
}
一旦你獲取到一個accessory對象,你就可以訪問它的服務(wù)和對象
- (五) 獲取Home中的Accessories屬性
使用HMHome類中的accessories的方法,可以直接從Home對象中獲取所有的accessory對象,而不用枚舉home中的所有room對象
創(chuàng)建Homes和添加Accessories
HomeKit對象被保存在一個可以共享的HomeKit數(shù)據(jù)庫里,它可以通過HomeKit框架被多個應(yīng)英程序訪問。
所有HomeKit調(diào)用的方法都是異步寫入的,并且這些方法都包含一個完成處理后的參數(shù)。如果這個方法處理成功了,你的應(yīng)用將會在完成處理函數(shù)里更新本地對象。
應(yīng)用程序啟動時,HomeKit對象發(fā)生改變的并不能收到代理回調(diào)?法,只能接受處理完成后的回調(diào)函數(shù)。
- (一) 創(chuàng)建Homes
在HMHomeManager類中使用addHomeWithName:completionHandler:異步方法可以添加一個home。作為參數(shù)傳到那個方法中的home的名字,必須是唯一獨特的,并且是Siri可以識別的home名字。
[self.homeManager addHomeWithName:@"My Home" completionHandler:^(HMHome *home, NSError *error) {
if (error != nil) {
// Failed to add a home
} else {
// Successfully added a home
}
}];
在else語句中,寫入代碼以更新你應(yīng)的程序的視圖
- (二) 在Home中增加一個Room
使用addRoomWithName:completionHandler: 異步方法可以在一個home中添加一個room對象。作為參數(shù)傳到那個方法中的room的名字,必須是唯一獨特的,并且是Siri可識別的room名字。
NSString *roomName = @"Living Room";
[home addRoomWithName:roomName completionHandler:^(HMRoom *room, NSError *error) {
if (error != nil) {
// Failed to add a room to a home
} else {
// Successfully added a room to a home
}
}];
在else語句中,寫入代碼更新應(yīng)用程序的視圖。
- (三)發(fā)現(xiàn)配件
Accessories封裝了物理配件的狀態(tài),因此它不能被用戶創(chuàng)建。想要允許用戶給家添加新的配件,我們可以使HMAccessoryBrowser對象找到一個與home沒有關(guān)聯(lián)的配件。HMAccessoryBrower 對象在后臺搜尋配件,當(dāng)它找到配件的時候,使用委托來通知你的應(yīng)用程序。只有在startSearchingForNewAccessories方法調(diào)用之后或者stopSearchingForNewAccessories方法調(diào)用之前,HMAccessoryBrowserDelegate消息才被發(fā)送給代理對象。
1> 發(fā)現(xiàn)home中的配件,在你的類接口中添加配件瀏覽器委托協(xié)議,并且添加一個配件瀏覽器屬性。代碼如下:
@interface EditHomeViewController ()
@property HMAccessoryBrowser *accessoryBrowser;
@end
2> 創(chuàng)建配件瀏覽器對象,并設(shè)置它的代理
self.accessoryBrowser = [[HMAccessoryBrowser alloc] init];
self.accessoryBrowser.delegate = self;
3> 開始搜尋配件
[self.accessoryBrowser startSearchingForNewAccessories];
4> 將找到的配件添加到你的收藏里
- (void)accessoryBrowser:(HMAccessoryBrowser *)browser didFindNewAccessory:(HMAccessory *)accessory {
// Update the UI per the new accessory; for example, reload a picker view.
[self.accessoryPicker reloadAllComponents];
}
用你自己的代碼實現(xiàn)上面的accessoryBrowser:didFindNewAccessory:方法。 當(dāng)然也可以實現(xiàn)accessoryBrowser:didRemoveNewAccessory: 這個方法來移除配件,這個配件對你的視圖或者收藏來說不再是新的。
5> 停止搜尋配件
如果一個視圖控制器正在開始搜尋配件,那么可以通過重寫viewWillDisappear:方法來停止搜尋配件。代碼如下:
- (void)viewWillDisappear:(BOOL)animated {
[self.accessoryBrowser stopSearchingForNewAccessories];
}
注意: 在WiFi網(wǎng)絡(luò)環(huán)境下,為了安全地獲取新的并且能夠被HomeKit發(fā)現(xiàn)的無線配件,請參閱External Accessory Framework Reference
- (四) 為Home和room添加配件(Accessory)
配件歸屬于home,并且它可以被隨意添加到home中的任意一個room中。使用addAccessory:completionHandler:這個異步方法可以在home中添加配件。這個配件的名字作為一個參數(shù)傳遞到上述異步方法中,并且這個名字在配件所屬的home中必須是唯一的。使用assignAccessory:toRoom:completionHandler:這個異步方法可以給home中的room添加配件。配件默認(rèn)的room 是roomForEntireHome這個方法返回值room。下面的代碼演示了如何給home和room添加配件:
// Add an accesory to a home and a room
// 1. Get the home and room objects for the completion handlers.
__block HMHome *home = self.home;
__block HMRoom *room = roomInHome;
// 2. Add the accessory to the home
[home addAccessory:accessory completionHandler:^(NSError *error) {
if (error) {
// Failed to add accessory to home
} else {
if (accessory.room != room) {
// 3. If successfully, add the accessory to the room
[home assignAccessory:accessory toRoom:room completionHandler:^(NSError *error) {
if (error) {
// Failed to add accessory to room
}
}];
}
}
}];
配件可提供一項或者多項服務(wù),這些服務(wù)的特性是由制造商定義。想了解配件的服務(wù)和特性目的,請參閱 Accessing Services and Characteristics.
- (五) 更改配件名稱
使用updateName:completionHandler:異步方法可以改變配件的名稱,代碼如下:
[accessory updateName:@"Kid's Night Light" completionHandler:^(NSError *error) {
if (error) {
// Failed to change the name
} else {
// Successfully changed the name
}
}];
(六) 為Homes和Room添加Bridge(橋接口)
橋接口是配件中的一個特殊對象,它允許你和其他配件交流,但是不允許你直接和HomeKit交流。例如一個橋接口可以是控制多個燈的樞紐,它使用的是自己的通信協(xié)議,而不是HomeKit配件通信協(xié)議。想要給home添加多個橋接口 ,你可以按照Adding Accessories to Homes and Rooms中所描述的步驟,添加任何類型的配件到home中。
正如Observing HomeKit Database Changes中所描述的那樣,每次更改通知設(shè)計模,home的代理不會接收到橋接口的home:didAddAccessory: 代理消息,而是接收一個有關(guān)于配件的home:didAddAccessory:代理消息。
在home中,要把橋接口后的配件和任何類型的配件看成一樣的--例如,把它們加入配件列表的配置表中。相反的是,當(dāng)你給room增添一個橋接口時,這個橋接口底層的配件并不會自動地添加到room中,原因是橋接口和它的的配件可以位于到不同的room中。-
(七)創(chuàng)建分區(qū)
分區(qū) 是任意可選的房間(rooms)分組;例如樓上、樓下或者臥室。房間可以被添加到一個或者多個區(qū)域。
zone.pngHMZone
可使用addZoneWithName:completionHandler: 異步方法創(chuàng)建分區(qū)。所創(chuàng)建的作為參數(shù)傳遞到這個方法中分區(qū)的名稱,在home中必須是唯一的,并且應(yīng)該能被Siri識別。代碼如下:
__block HMHome *home = self.home;
NSString *zoneName = @"Upstairs";
[home addZoneWithName:zoneName completionHandler:^(HMZone *zone, NSError *error){
if (error) {
// Failed to create zone
} else {
// Successfully created zone, now add the rooms
}
}];
可使用addRoom:completionHandler:異步方法給分區(qū)添加一個room,代碼如下:
__block HMRoom *room = roomInHome;
[zone addRoom:room completionHandler:^(NSError *error) {
if (error) {
// Failed to add room to zone
} else {
// Successfully added room to zone
}
}];
