HomeKit對象被保存在一個可以共享的HomeKit數據庫里,它可以通過HomeKit框架被多個應英程序訪問。所有HomeKit調用的方法都是異步寫入的,并且這些方法都包含一個完成處理后的參數。如果這個方法處理成功了,你的應用將會在完成處理函數里更新本地對象。應用程序啟動時,HomeKit對象發生改變的并不能收到代理回調?法,只能接受處理完成后的回調函數。
想要觀察其他應用程序啟動時HomeKit對象的變化,請參閱:[Observing HomeKit Database Changes](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/RespondingtoHomeKitDatabaseChanges/RespondingtoHomeKitDatabaseChanges.html#//apple_ref/doc/uid/TP40015050-CH5-SW2)。查閱異步消息完成處理后傳過來的錯誤碼的信息,請參閱:[HomeKit Constants Reference](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HomeKit_Constants/index.html#//apple_ref/doc/uid/TP40014524).
**對象命名規則**
HomeKit對象的名字,例如home、room和zone對象都可以被Siri識別,這一點已經在文檔中指出。以下幾點是HomeKit對象的命名規則:
* 對象名字在其命名空間內必須是唯一的。
* 屬于用戶所有的home名字都在一個命名空間內。
* 一個home對象及其所包含的對象在另一個命名空間內。
* 名字只能包含數字、字母、空格以及省略號字符。
* 名字必須以數字或者字母字符開始。
* 在名字比較的時候,空格或者省略號是忽略的(例如home1和home 1 同一個名字)。
* 名字沒有大小寫之分。
想了用戶可以使用哪些語言與Siri進行交互,請參閱[HomeKit User Interface Guidelines](https://developer.apple.com/homekit/ui-guidelines/)文檔中的"Siri Integration"
**創建Homes**
在[HMHomeManager](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHomeManager_Class/index.html#//apple_ref/occ/cl/HMHomeManager)類中使用[addHomeWithName:completionHandler:?](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHomeManager_Class/index.html#//apple_ref/occ/instm/HMHomeManager/addHomeWithName:completionHandler:)異步方法可以添加一個home。作為參數傳到那個方法中的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語句中,寫入代碼以更新你應的程序的視圖。為了獲取home manager對象,請參閱[Getting the Home Manager Object](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/FindingandAddingAccessories/FindingandAddingAccessories.html#//apple_ref/doc/uid/TP40015050-CH3-SW2).
**在Home中增加一個Room**
使用[addRoomWithName:completionHandler:?](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHome_Class/index.html#//apple_ref/occ/instm/HMHome/addRoomWithName:completionHandler:)異步方法可以在一個home中添加一個room對象。作為參數傳到那個方法中的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語句中,寫入代碼更新應用程序的視圖。
**發現配件**
Accessories封裝了物理配件的狀態,因此它不能被用戶創建。想要允許用戶給家添加新的配件,我們可以使[HMAccessoryBrowser對象](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowser_Class/index.html#//apple_ref/occ/cl/HMAccessoryBrowser)找到一個與home沒有關聯的配件。[HMAccessoryBrower](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowser_Class/index.html#//apple_ref/occ/cl/HMAccessoryBrowser)對象在后臺搜尋配件,當它找到配件的時候,使用委托來通知你的應用程序。只有在[startSearchingForNewAccessories](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowser_Class/index.html#//apple_ref/occ/instm/HMAccessoryBrowser/startSearchingForNewAccessories)方法調用之后或者[stopSearchingForNewAccessories](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowser_Class/index.html#//apple_ref/occ/instm/HMAccessoryBrowser/stopSearchingForNewAccessories)方法調用之前,[HMAccessoryBrowserDelegate](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowserDelegate_Protocol/index.html#//apple_ref/occ/intf/HMAccessoryBrowserDelegate)消息才被發送給代理對象。
**發現home中的配件**
1\. 在你的類接口中添加配件瀏覽器委托協議,并且添加一個配件瀏覽器屬性。代碼如下:
~~~
@interface EditHomeViewController ()
@property HMAccessoryBrowser *accessoryBrowser;
@end
~~~
用你自己的類名代替EditHomeViewController
2\. 創建配件瀏覽器對象,并設置它的代理
~~~
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];
}
~~~
用你自己的代碼實現上面的[accessoryBrowser:didFindNewAccessory:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowserDelegate_Protocol/index.html#//apple_ref/occ/intfm/HMAccessoryBrowserDelegate/accessoryBrowser:didFindNewAccessory:)方法。 當然也可以實現[accessoryBrowser:didRemoveNewAccessory:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessoryBrowserDelegate_Protocol/index.html#//apple_ref/occ/intfm/HMAccessoryBrowserDelegate/accessoryBrowser:didRemoveNewAccessory:)?這個方法來移除配件,這個配件對你的視圖或者收藏來說不再是新的。
5\. 停止搜尋配件
如果一個視圖控制器正在開始搜尋配件,那么可以通過重寫[viewWillDisappear:](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/viewWillDisappear:)方法來停止搜尋配件。代碼如下:
~~~
- (void)viewWillDisappear:(BOOL)animated {
[self.accessoryBrowser stopSearchingForNewAccessories];
}
~~~
注意: 在WiFi網絡環境下,為了安全地獲取新的并且能夠被HomeKit發現的無線配件,請參閱[External Accessory Framework Reference](https://developer.apple.com/library/ios/documentation/ExternalAccessory/Reference/ExternalAccessoryFrameworkReference/index.html#//apple_ref/doc/uid/TP40008235).
**為Home和room添加配件(Accessory)**
配件歸屬于home,并且它可以被隨意添加到home中的任意一個room中。使用[addAccessory:completionHandler:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHome_Class/index.html#//apple_ref/occ/instm/HMHome/addAccessory:completionHandler:)這個異步方法可以在home中添加配件。這個配件的名字作為一個參數傳遞到上述異步方法中,并且這個名字在配件所屬的home中必須是唯一的。使用[assignAccessory:toRoom:completionHandler:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHome_Class/index.html#//apple_ref/occ/instm/HMHome/assignAccessory:toRoom:completionHandler:)?這個異步方法可以給home中
的room添加配件。配件默認的room是[roomForEntireHome](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHome_Class/index.html#//apple_ref/occ/instm/HMHome/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
} }];
} }
}];
~~~
配件可提供一項或者多項服務,這些服務的特性是由制造商定義。想了解配件的服務和特性目的,請參閱?[Accessing Services and Characteristics](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/AccessingServicesandTheirCharacteristics/AccessingServicesandTheirCharacteristics.html#//apple_ref/doc/uid/TP40015050-CH6-SW1).
**更改配件名稱**
使用[updateName:completionHandler:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMAccessory_Class/index.html#//apple_ref/occ/instm/HMAccessory/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交流。例如一個橋接口可以是控制多個燈的樞紐,它使用的是自己的通信協議,而不是HomeKit配件通信協議。想要給home添加多個橋接口 ,你可以按照[Adding Accessories to Homes and Rooms](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/WritingtotheHomeKitDatabase/WritingtotheHomeKitDatabase.html#//apple_ref/doc/uid/TP40015050-CH4-SW5)中所描述的步驟,添加任何類型的配件到home中。當你給home添加一個橋接口時,在橋接口底層的配件也會被添加到home中。正如[Observing HomeKit Database Changes](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/RespondingtoHomeKitDatabaseChanges/RespondingtoHomeKitDatabaseChanges.html#//apple_ref/doc/uid/TP40015050-CH5-SW2)中所描述的那樣,每次更改通知設計模,home的代理不會接收到橋接口的[home:didAddAccessory:?](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHomeDelegate_Protocol/index.html#//apple_ref/occ/intfm/HMHomeDelegate/home:didAddAccessory:)代理消息,而是接收一個有關于配件的[home:didAddAccessory:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHomeDelegate_Protocol/index.html#//apple_ref/occ/intfm/HMHomeDelegate/home:didAddAccessory:)代理消息。在home中,要把橋接口后的配件和任何類型的配件看成一樣的--例如,把它們加入配件列表的配置表中。相反的是,當你給room增添一個橋接口時,這個橋接口底層的配件并不會自動地添加到room中,原因是橋接口和它的的配件可以位于到不同的room中。
**創建分區**
分區 ([HMZone](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMZone_Class/index.html#//apple_ref/occ/cl/HMZone)) 是任意可選的房間(rooms)分組;例如樓上、樓下或者臥室。房間可以被添加到一個或者多個區域。

可使用[addZoneWithName:completionHandler:?](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMHome_Class/index.html#//apple_ref/occ/instm/HMHome/addZoneWithName:completionHandler:)異步方法創建分區。所創建的作為參數傳遞到這個方法中分區的名稱,在home中必須是唯一的,并且應該能被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:](https://developer.apple.com/library/ios/documentation/HomeKit/Reference/HMZone_Class/index.html#//apple_ref/occ/instm/HMZone/addRoom:completionHandler:)異步方法給分區添加一個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
} }];
~~~