1. 程式人生 > >HomeKit 開發指南(中文版)

HomeKit 開發指南(中文版)

第一部分:簡介

第二部分:啟用HomeKit

第三部分:建立Home佈局

第四部分:建立Homes和新增Accessories

第五部分:觀察HomeKit資料庫的變化

第六部分:訪問服務和特性

第七部分:測試HomeKitApp

第八部分:建立動作集(Action Sets)和觸發器(Triggers)

第九部分:使用者管理

第一部分:簡介

該文件旨在幫你編寫HomeKit app。HomeKit庫是用來溝通和控制家庭自動化配件的,這些家庭自動化配件都支援蘋果的HomeKit Accessory Protocol。HomeKit應用程式可讓使用者發現相容配件並配置它們。使用者可以建立一些action來控制智慧配件(例如恆溫或者光線強弱),對其進行分組,並且可以通過Siri觸發。HomeKit 物件被儲存在使用者iOS裝置的資料庫中,並且通過iCloud還可以同步到其他iOS裝置。HomeKit支援遠端訪問智慧配件,並支援多個使用者裝置和多個使用者。HomeKit 還對使用者的安全和隱私做了處理。

into_diagram_2x.png

注意:如果你是開發設計HomeKit硬體的供應商,你可以去Hardware Developers下的HomeKit頁面瞭解MFi Program相關資訊,也可以閱讀 External Accessory Programming Topics.

另請參閱

以下資源提供了更多關於建立HomeKit應用程式的資訊:

第二部分:啟用HomeKit

HomeKit應用服務只提供給通過App Store釋出的app應用程式。在你的Xcode工程中, HomeKit應用程式需要額外的配置,你的app必須有開發證書和程式碼簽名才能使用HomeKit。在Xcode的Capabilities面板使用HomeKit,可避免程式碼簽名的問題。你無需直接在Xcode或者會員中心編輯授權檔案(entitlements)。

設定

為了完成本文件中所有步驟,你需要:

  1. 一個安裝Xcode 6 或者Xcode 6 以上版本的Mac電腦。

  2. 為了獲得最佳體驗,你的Mac電腦上最好安裝最新的OS X 系統和最新的Xcode 版本。

  3. 加iOS開發者計劃。

  4. 在Member Center 擁有建立程式碼簽名和資源配置的許可權。

在你開始使用HomeKit之前,請確保你已經完成以下任務。建立你團隊的配置檔案(Provisioning Profile),請參閱:App Distribution Quick Start .

當你成功地完成了之前的任務後,General面板中Team彈出選單中的錯誤資訊和問題修復按鈕將會消失。程式碼簽名配置被成功建立後會展示下方的General面板。

61.png


啟用HomeKit

想要使用HomeKit,首先要啟用它。Xcode將會新增HomeKit許可權到你的工程授權檔案中和會員中心的App ID授權檔案中,也會將HomeKit框架新增到你的工程中。HomeKit 需要一個明確的App ID, 這個App ID是為了你完成這些步奏而建立的。

啟用HomeKit的步驟如下:

  1. 在Xcode中,選擇View > Navigators > Show Project Navigator。

  2. 從Project/Targets彈出選單中target(或者從Project/Targets的側邊欄)

  3. 點選Capabilities檢視你可以新增的應用服務列表。

  4. 滑到HomeKit 所在的行並開啟關。

下載HomeKit Accessory Simulator

無需為了開發Homekit 應用程式而購買硬體產品。你可以使HomeKit Accessory Simulator來測試HomeKit app和模擬配件裝置之間的通訊。HomeKit Accessory Simulator不是和Xcode一起釋出的。 

下載HomeKit Accessory Simulator步驟如下:

  1. 在Capabilities面板的HomeKit分割槽,點選Download HomeKit Accessory Simulator按鈕。(或者選擇Xcode > Open Developer Tool > More Developer Tools)

  2. 在瀏覽器中搜索並且下載"Hardware IO Tools for Xcode ".dmg檔案。

  3. 在 Finder中雙擊~/Downloads中的.dmg檔案。

  4. 把HomeKit Accessory Simulator拖拽到/Application檔案中。

之後,你將可以使用HomeKit Accessory Simulator測試你的HomeKit應用程式,正如Testing YourHomeKit App(第30頁)中描述的那樣。

第三部分:建立Home佈局

HomeKit 允許使用者建立一個或者多個Home佈局。每個Home(HMHome)代表一個有網路裝置的住所。使用者擁有Home的資料並可通過自己的任何一臺iOS裝置進行訪問。使用者也可以和客戶共享一個Home,但是客戶的許可權會有更多限制。被指定為primary home的home預設是Siri指令的物件,並且不能指定home。

每個Home一般有多個room,並且每個room一般會有多個智慧配件。在home(HMHome) 中,每個房間是獨立的room,並具有一個有意義的名字,例如“臥室”或者“廚房”,這些名字可以在Siri 命令中使用。一個accessory(HMAccessory)代表實際家庭中的自動化裝置,例如車庫開門器。一個sevice(HMService)是accessory提供的?種實際服務,例如開啟或者關閉車庫,或者車庫上的燈。

homes_2x.png

如果你的app 快取了home佈局的資訊,那麼當其佈局發聲改變的時候,app就需要更新這些資訊。使用HMHomeManager物件可以從HomeKit資料庫獲取HMHome和其他相關的物件。本章描述的API獲取物件後,你應該通過代理回撥函式保持獲取物件和HomeKit資料庫同步,具體描述請參看“Observing HomeKit Database Changes".

建立 Home Manager物件

使用Home Manager—一個HMHomeManager物件的訪問home、room、配件、服務以及其他HomeKit物件。在建立家庭物件管理器(home manager)之後,直接設定它的代理,以便獲取到這些物件之後及時的通知到你。

self.homeManager = [[HMHomeManager alloc] init];
 self.homeManager.delegate = self;

當你建立一個home manager物件時,HomeKit就開始從HomeKit資料庫獲取這些homes和相關物件,例如room和accessory物件。當HomeKit正在獲取那些物件時,home manager 的primaryHome屬性是nil,並且homes屬性是個空陣列。你的app應該處理使用者還沒有完成建立home的情況,但是app應該等待直到HomeKit完成初始化。當獲取物件完成之後,HomeKit 會發送homeManagerDidUpdateHomes:訊息給home manager的代理。
注意:當app進入前臺或者在後臺Home manager屬性發生改變時,這個homeManagerDidUpdateHomes:方法就會被呼叫,詳情請參閱“Observing Changes to the Collection of Homes”。

獲取Primary Home和 Homes集合

通過home manager的primaryHome屬性,可以得到primary home,程式碼如下:

HMHome *home = self.homeManager.primaryHome;

使用home manager的homes屬性可以得到使用者的所有home的集合;例如自家主要居所、度假別墅以及辦公室。每個home都對應一個獨立的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 陣列屬於home,但是被指定給了home中的room。假如使用者沒有給一個accessory指定room,那麼這個accessories被指定一個預設的room ,這個room是roomForEntireHome方法的返回值。用room的accessories屬性可以列舉room中所有的accessory。程式碼如下:

HMAccessory *accessory;
 for(accessory in room.accessories){
 …
 }

如果你要展示一個個accessory的相關資訊或者允許使用者控制它,可設定accessory的代理方法並實現這個代理方法,詳情請見“Observing Changes to Accessories”.
一旦你獲取到一個accessory物件,你就可以訪問它的服務和物件,詳情請參閱“Accessing Services and Characteristics”。

獲取Home中的Accessories屬性

使用HMHome類中的accessories的方法,可以直接從Home物件中獲取所有的accessory物件,而不用列舉home中的所有room物件(詳情請見“Getting the Accessories in a Room”。

第四部分:建立Homes和新增Accessories

HomeKit物件被儲存在一個可以共享的HomeKit資料庫裡,它可以通過HomeKit框架被多個應英程式訪問。所有HomeKit呼叫的方法都是非同步寫入的,並且這些方法都包含一個完成處理後的引數。如果這個方法處理成功了,你的應用將會在完成處理函式裡更新本地物件。應用程式啟動時,HomeKit物件發生改變的並不能收到代理回撥?法,只能接受處理完成後的回撥函式。

物件命名規則

HomeKit物件的名字,例如home、room和zone物件都可以被Siri識別,這一點已經在文件中指出。以下幾點是HomeKit物件的命名規則:

  • 物件名字在其名稱空間內必須是唯一的。

  • 屬於使用者所有的home名字都在一個名稱空間內。

  • 一個home物件及其所包含的物件在另一個名稱空間內。

  • 名字只能包含數字、字母、空格以及省略號字元。

  • 名字必須以數字或者字母字元開始。

  • 在名字比較的時候,空格或者省略號是忽略的(例如home1和home 1 同一個名字)。

  • 名字沒有大小寫之分。

想了使用者可以使用哪些語言與Siri進行互動,請參閱HomeKit User Interface Guidelines文件中的"Siri Integration"

建立Homes

[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.

在Home中增加一個Room

使用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語句中,寫入程式碼更新應用程式的檢視。

發現配件

發現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];
}

5. 停止搜尋配件

如果一個檢視控制器正在開始搜尋配件,那麼可以通過重寫viewWillDisappear:方法來停止搜尋配件。程式碼如下:

- (void)viewWillDisappear:(BOOL)animated {
[self.accessoryBrowser stopSearchingForNewAccessories];
}

為Home和room新增配件(Accessory)

配件歸屬於home,並且它可以被隨意新增到home中的任意一個room中。使用addAccessory:completionHandler:這個非同步方法可以在home中新增配件。這個配件的名字作為一個引數傳遞到上述非同步方法中,並且這個名字在配件所屬的home中必須是唯一的。使用assignAccessory:toRoom:completionHandler: 這個非同步方法可以給home中

的room新增配件。配件預設的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
} }];
} }
}];

更改配件名稱

[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中所描述的步驟,新增任何型別的配件到home中。當你給home新增一個橋介面時,在橋介面底層的配件也會被新增到home中。正如Observing HomeKit Database Changes中所描述的那樣,每次更改通知設計模,home的代理不會接收到橋介面的home:didAddAccessory: 代理訊息,而是接收一個有關於配件的home:didAddAccessory:代理訊息。在home中,要把橋介面後的配件和任何型別的配件看成一樣的--例如,把它們加入配件列表的配置表中。相反的是,當你給room增添一個橋介面時,這個橋介面底層的配件並不會自動地新增到room中,原因是橋介面和它的的配件可以位於到不同的room中。

建立分割槽

分割槽 (HMZone) 是任意可選的房間(rooms)分組;例如樓上、樓下或者臥室。房間可以被新增到一個或者多個區域。

zones_2x.png

可使用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
}
}];
__block HMRoom *room = roomInHome;
[zone addRoom:room completionHandler:^(NSError *error) {
if (error) {
// Failed to add room to zone
} else {
// Successfully added room to zone
} }];

第五部分:觀察HomeKit資料庫的變化

每個Home都有一個HomeKit資料庫。如下圖所示,HomeKit資料庫會安全地和home授權的使用者的iOS裝置以及潛在的客人的iOS裝置進行同步。為了給使用者展示當前最新的資料,你的應用需要觀察HomeKit資料庫的變化。

HomeKit代理方法

HomKit使用代理設計模式(delegation design pattern)來通知應用程式HomeKit物件的改變。一般來講,如果你的應用程式呼叫了一個帶有完成處理引數的HomeKit方法,並且這個方法被成功呼叫了,那麼相關聯的代理訊息就會被髮送給其他HomeKit應用,無論這些應用是安裝在同一臺iOS裝置上還是遠端iOS裝置上。這些應用甚至可以執行在客人的iOS裝置上。如果你的應用發起了資料改變,但是代理訊息並沒有傳送到你的應用,那麼新增程式碼到完成處理方法和相關聯的代理方法中來重新整理資料和更新檢視就成為必須了。如果home佈局發生了顯著變化,那麼就重新載入關於這個home的所有資訊。在完成程式處理的情況下,請在更新應用之前檢查那個方法是否成功。Homkit也會呼叫代理方法來通知你的應用程式home網路狀態的改變。

例如,下圖演示了使用代理方法的過程:響應使用者的操作,你的應用程式呼叫了addRoomWithName:completionHandler:方法,並且沒有錯誤發生,完成處理程式應當更新home的所有檢視。如果成功了,homeKit將會發送home:didAddRoom:訊息給其他應用中homes的代理。因此,你實現的這個home:didAddRoom:方法也應該更新home的所有檢視。

應用程式只有在前臺執行的時候才能接受代理訊息。當你的應用在後臺時,HomeKit資料庫的改變並不會成批處理。也就是說,如果你的應用在後臺,當其他的應用成功地新增一個room到home中的時候,你的應用程式並不會接收到home:didAddRoom: 訊息。當你的應用程式到前臺執行時,你的應用程式將會接收到homeManagerDidUpdateHomes:訊息,這個訊息是表示你的應用程式要重新載入所有的資料。

觀察Homes集合的改變

設定home manager的代理並且實現HMHomeManagerDelegate協議,當primary home或者home集合發生改變時,可以接收代理訊息。

所有的應用都需要實現homeManagerDidUpdateHomes:方法,這個方法在完成最初獲取homes之後被呼叫。對新建的home manager來說,在這個方法被呼叫之前,primaryHome屬性的值是nil,homes陣列是空的陣列。當應用程式開始在前臺執行時也會呼叫 homeManagerDidUpdateHomes: 方法,當其在後臺執行時資料發生改變。該homeManagerDidUpdateHomes:方法會重新載入與homes相關聯的所有資料。

觀察homes的變化

1.在你的類介面中新增HMHomeManagerDelegate代理和homeManager屬性。程式碼如下:

@interface AppDelegate () @property (strong, nonatomic) HMHomeManager *homeManager;
@end

2.建立home manager物件並設定其代理

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.homeManager = [[HMHomeManager alloc] init];
self.homeManager.delegate = self;
return YES;
}

3. 實現homes發生改變時呼叫的代理方法。例如:如果多個檢視控制器展示了homes相關資訊,你可以釋出一個更改通知去更新所有檢視。

- (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];
}

檢視控制器註冊更改通知並且執行適當的操作。

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateHomes:)
name:@"UpdateHomesNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updatePrimaryHome:)
name:@"UpdatePrimaryHomeNotification" object:nil];

觀察個別home的變化

展示home資訊的檢視控制器應該成為home物件的代理,並且當home發生改變時更新檢視控制器的檢視。

觀察特定home物件的改變

1.在類介面中新增home代理協議。

@interface HomeViewController () @end

2.設定配件代理

home.delegate = self;

Bridge Note:當你為home新增橋介面時,橋介面底層的配件會自動被新增到home中。你的代理會接收到橋介面後每個配件的 home:didAddAccessory:訊息,但是你的代理不會接收到橋介面的home:didAddAccessory:訊息。

觀察配件的變化

配件的狀態可以在任何時間發生變化。配件可能不能被獲得,可以被移除,或者被關閉。請更新使用者介面以反映配件狀態的更改,尤其是如果你的app允許使用者控制配件時。

這以下步驟中,我們假設你已經從HomeKit資料庫中檢索到了配件物件,正如Getting the Accessories in a Room中描述的那樣。

觀察個別配件的變化

  1. 在類介面中新增配件代理協議。

@interface AccessoryViewController ()  
@end

2. 設定配件的代理

accessory.delegate = self;
- (void)accessoryDidUpdateReachability:(HMAccessory *)accessory {
    if (accessory.reachable == YES) {
       // Can communicate with the accessory
    } else {
       // The accessory is out of range, turned off, etc
    }
}

如果你展示了配件的服務狀態和特性,那麼請執行以下代理方法來相應地更新其檢視:

第六部分:訪問服務和特性

服務(HMService)代表了一個配件(accessory)的某個功能和一些具有可讀寫的特性(HMCharacteristic)。一個配件可以擁有多項服務,一個服務也可以有很多特性。比如一個車庫開門器可能擁有一個照明和開關的服務。照明服務可能擁有開啟/關閉和調節亮度的特性。使用者不能製造智慧家電配件和它們的服務-配件製造商會製造配件和它們的服務-但是使用者可以改變服務的特性。一些擁有可讀寫屬性的特性代表著某種物理狀態,比如,一個恆溫器中的當前溫度就是一個只可讀的值,但是目標溫度又是可讀寫的。蘋果預先定義了一些服務和特性的名稱,以便讓Siri能夠識別它們。

獲得配件的服務和屬性

在依照Getting the Accessroties in a Room中描述,你建立了一個配件物件之後,你可以獲得配件的服務和特性。當然你也可以直接從home中按照型別獲得不同的服務。

重要:不要暴露匿名服務-比如韌體升級服務-給使用者

NSArray *services = accessroy.services;
// Get all lights and thermostats in a home
NSArray *lightServices = [home servicesWithTypes:[HMServicesTypeLightbulb]];
NSArray *thermostatServices = [home servicesWithTypes:[HMServicesTypeThermostat]];

使用HMServices類物件的name屬性來獲得服務的名稱

NSString *name = services.name;
NSArray *characteristics = service.characteristics

NSString *serviceType = service.serviceType;

蘋果定義了一些服務型別,並能被Siri識別:

  • 門鎖(Door locks)

  • 車庫開門器(Garage door openers)

  • 燈光(Lights)

  • 插座(Outlets)

  • 恆溫器(Thermostats)

改變服務名稱

使用updateName:completionHandler:非同步方法來改變服務名稱。傳入此方法的服務名稱引數必須在一個home當中是唯一的,並且服務名可被Siri識別。

[service updateName:@"Garage 1 Opener" completionHandler:^(NSError *error) {
    if (error) {
        // Failed to change the name
    } else {
        // Successfully changed the name
    }
}];

訪問特性的值

特性代表了一個服務的一個引數,它要麼是隻讀、可讀寫或者只寫。它提供了這個引數可能的值的資訊,比如,一個布林或者一個範圍值。恆溫器中的溫度就是隻讀的,而目標溫度又是可讀寫的。一個執行某個任務的命令且不要求任何返回-比如播放一段聲音或者閃爍一下燈光來確認某個配件-可能就是隻寫的。

蘋果定義了一些特性的型別,並能被Siri識別:

  • 亮度(Brightness)

  • 最近溫度(Current temperature)

  • 鎖的狀態(Lock state)

  • 電源的狀態(Power state)

  • 目標狀態(Target state)

  • 目標溫度(Target temperature)

比如,對於一個車庫開門器來說,目標狀態就是開啟或者關閉。對於一個鎖來說,目標狀態又是上鎖和未上鎖。

在你獲得了一個HMService物件之後,如 Getting Services and Their Properties所描述的,你可以獲得每個服務的特性的值。因為這些值是從配件中獲得的,這些讀寫的方法都是非同步的,並可以傳入一個完成回撥的block。

[characteristic readValueWithCompletionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully read the value
       id value = characteristic.value;
    }
    else {
       // Unable to read the value
} }];

在if語句塊中,加入你的程式碼以更新app的檢視。

[self.characteristic writeValue:@42 withCompletionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully wrote the value
    }
    else {
       // Unable to write the value
} }];

不要以為函式呼叫完成就意味著寫入成功,實際上只有在當完成回撥執行並沒有錯誤產生時才表示寫入成功。比如,直到一個開關的特性改變之前都不要改變這個開關的狀態。在if語句塊中,加入你的程式碼,以更新app的檢視。

建立服務組

一個服務組(HMServiceGroup)提供了控制不同配件的任意數量服務的快捷方式-比如,當用戶離開家之後控制家中的某些燈。

[self.home addServiceGroupWithName:@"Away Lights" completionHandler:^(HMServiceGroup *serviceGroup, NSError *error) {
    if (error == nil) {
       // Successfully created the service group
} else {
       // Unable to create the service group
    }];
[serviceGroup addService:service completionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully added service to service group
    }
       // Unable to add the service to the service group
    }];
NSArray *serviceGroups = self.home.serviceGroups;
HMAccessory *accessory = service.accessory;

和配件類似,代理方法在別的app改變服務組時也會被呼叫。如果你的app使用了服務組,請閱讀HMHomeDelegate Protocol Reference文件,獲悉你應該實現哪些方法以觀察這些變化。

第七部分:測試HomeKitApp

如果你沒有智慧電器(智慧配件),你可以使用HomeKit Accessroy Simulator來模擬home中的智慧電器。每個模擬配件都擁有服務和特性,你可以從你的App當中控制它。你的App在HomeKit資料庫中建立物件和關係。它可以建立home佈局,可以新增新的配件到模擬的home環境當中,最後向home中的每個房間新增智慧配件。然後,你的app就能控制這些在HomeKit Accessory Simulator展示的模擬智慧配件了。為了使用HomeKit Accessory Simulator,請在iOS模擬器中執行你的應用程式,或者使用Xcode在iOS裝置上執行應用程式。

HomeKit Accessory Simulator是一個附加的開發者工具,不過並沒有安裝在Xcode當中。請按照Download HomeKit Accessory Simulator中所述的安裝HomeKit Accessory Simulator。

新增智慧電器(配件)

使用HomeKit Accessory Simulator來新增智慧電器到模擬網路中。

向網路中新增智慧電器配件,請按照下面的步驟新增:

  1. 在HomeKit Accessory Simulator中,點選底部左邊‘+’按鈕。

  2. 從彈出選單中選擇新增智慧電器(Add Accessory)

  3. 輸入智慧電器的名字和製造商。

4.  點選完成

如果想刪除一個智慧電器,請選擇一個智慧電器然後點選鍵盤上的Delete鍵。

向智慧電器(配件)中新增服務

一個智慧電器需要一項服務和特性,你可以從app控制它。從預定義了服務列表中選擇一項服務,並自定義特性。

按照下面步驟向智慧電器中新增服務

  1. 在HomeKit Accessory Simulator中,選擇Accessories列中的某個配件。

該配件的服務資訊會展示在一個詳情介面中。

注意:所有智慧電器都有一個Accessory Information,顯示在所有其他服務的下方。你可以向這個Accessory Information服務新增特性,但你不能刪除預設的特性。

2.  點選新增服務(Add Service),並從彈出檢視中選擇一個服務型別。

新新增的服務會在右邊詳細顯示。HomeKit Accessory Simulator為每種服務建立通用的特性。比如一個燈光服務的預設特性為色彩(Hue),飽和度(Saturation),亮度(Brightness)和開關。(開關特性和電源狀態特性是一樣的,正如 Accessing Values of Characteristics中描述的那樣。)一些特性是強制性的有一些也是可選擇的。比如,開關特性就是強制性的,而色彩,飽和度,亮度這些特性都是可選擇的。

向服務中新增特性

你可以向服務中新增預定義的特性,或者自定義的特性。每種特性你都只能新增一個。

按照下面的步驟向服務中新增特性:

  1. 在HomeKit Accessory Simulator中,服務詳情檢視,點選新增特性(Add Characteristic)

  2. 在特性型別選單中,選擇一個型別或者自定義型別。

  3. 在其他文字框中輸入此特性的其他資訊,並點選完成(Finish).新新增的特性會在詳細檢視展示出來。

點選特性右邊的減號來刪除一個特性。如果特性右邊並沒有減號顯示,這說明這個特性對這個服務來說是必須的。比如,你可以刪除電燈服務中的色彩(Hue),飽和度(Saturation)和亮度(Brightness),但是你不可以刪除開關特性。

通過你的app向家庭中新增智慧電器(配件)

在你通過HomeKit Accessory Simulator建立了一個智慧電器後,執行你的App然後新增一個新的智慧電器到你的家庭。

如何配對家庭中的智慧電器:

2.  如果彈出了一個Add HomeKit Accessory對話方塊宣告這個智慧電器未被信任(這在HomeKit Accessory Simulator中是被允許的),不用管它,點選Add Anyway。

3.  在接下來顯示的Add HomeKit Accessory對話方塊中,輸入智慧電器的setup code然後點選Add。

在HomeKit Accessory Simulator,setup code顯示在詳情介面智慧電器名稱下。

控制智慧電器(配件)

在HomeKit Accessory Simulator中,你可以獲得智慧電器的服務,並在其他HomeKit App中設定服務的特性值來模擬控制這個智慧電器,或者手動地模擬控制智慧電器。

想要控制一個智慧電器你需要:

  1. 在HomeKit Accessory Simulator中的智慧電器列表(Accessories column)中選擇一個智慧電器。這個智慧電器的服務和特性會被展示在詳情介面。

  2. 操作一個特性的控制元件來改變它的值。

比如,為了改變一個燈泡的顏色(Hue),飽和度(Saturation)和亮度(Brightness),請滑動這個滑塊。為了開啟這個燈泡請選擇On選項。

如果你的app展示了一個服務的特性,比如燈泡的開關狀態,當你在HomeKit Accessory Simulator中改變這些特性的值時,它應當更新檢視。

新增橋介面

為了模擬那些不支援HomeKit Accessory Protocol協議的智慧電器,需要新增一個虛擬橋介面,然後將智慧電器新增到這個虛擬橋介面。配置虛擬橋介面底層的智慧電器和配置其他型別的智慧電器差不多。

新增一個虛擬橋介面到網路

新增一個代表這個虛擬橋介面的智慧電器。

為了新增一個虛擬橋介面到網路你需要:

1.  在HomeKit Accessory Simulator中,點選智慧電器列表底部的“+”按鈕。

2.  在彈出框中選擇Add 虛擬橋介面。

3.  輸入一個智慧電器的名稱和製造商。

4.  點選完成

向虛擬橋介面新增智慧電器配件
可向一個虛擬橋介面新增一個或多個智慧電器。

為了向一個虛擬橋介面新增一個智慧電器,需要:

  1. 在HomeKit Accessory Simulator左邊的列表中,選擇虛擬橋介面中的一個虛擬橋介面。

  2. 在詳情頁面選擇Add Accessory。

  3. 輸入一個智慧電器名字和製造商。

  4. 點選完成。

想要了解虛擬橋介面中的智慧電器的詳細資訊,請選擇虛擬橋介面部分中的智慧電器。如果需要的話你可以點選虛擬橋介面旁邊的檢視詳情來檢視這個虛擬橋介面的智慧電器。在你添加了一個服務和特性到這些智慧電器之後,如Adding Services to AccessoriesAdding Characteristics to Services中描述。它們會在這個虛擬橋介面被選擇之後被展示出來。

在你的App中新增虛擬橋介面到home

控制虛擬橋介面底層的智慧電器

在多裝置和多使用者環境中測試

在iOS模擬器中你不能測試分享HomeKit資料庫到多個iOS裝置和使用者。你應該安裝你的App到多臺iOS裝置上,在這些裝置中輸入iCloud證書,然後執行你的App。或者,使用ad hoc授權來在多臺註冊裝置中測試你的app,如Distributing Your App Using Ad Hoc Provisioning in App Distribution Guide描述。

  1. 為了測試單使用者多裝置環境,你應該使用同一個iCloud賬戶在多臺裝置登陸。

  2. 為了測試多使用者使用同一家庭的智慧電器,你應該在多臺裝置使用不同的iCloud賬戶登陸。

你的App應該應該可以允許一個使用者邀請客人到你的家中,如Managing Users所述。

第八部分:建立動作集(Action Sets)和觸發器(Triggers)

一個動作集合HMActionSet和觸發器HMTimerTrigger允許你同時控制多個智慧電器。比如,一個動作集合可能會在使用者上床休息之前執行一組動作HMAction。一個寫動作向一個特性寫入了值。動作集合中的動作是以不確定的順序執行的。一個觸發器會在一個特定的時間出發一個動作集並可以重複執行。每一個動作集合在一個家庭中都有唯一的名稱並可被Siri識別。

建立寫入動作

寫入動作會向一個服務的特性寫入值並被加入到動作集合中去。HMAction類是HMCharacteristicWriteAction具體類的抽象基類。一個動作有一個相關聯的特性物件,你可以通過Accessing Services and Characteristics中描述的來獲取相關的服務和特性,然後建立這個HMCharacteristicWriteAction

HMCharacteristicWriteAction *action = [[HMCharacteristicWriteAction alloc] initWithCharacteristic:characteristic targetValue:value];

在你的程式碼中,你使用對應的特性的期望來替換value引數,並使用對應的HMCharacteristic物件來替換characteristic引數。

建立並執行動作集

一個動作集就是一個共同執行的動作的集合。比如一個夜間動作集合可能包含關閉電燈,調低恆溫水平和鎖上房門。

[self.home addActionSetWithName:@"NightTime" completionHandler:^(HMActionSet *actionSet, NSError *error) {
    if (error == nil) {
        // 成功添加了一個動作集
    } else {
        // 新增一個動作集失敗
    }
}];
[actionSet addAction:action completionHandler:^(NSError *error) {
    if (error == nil) {
        // 成功添加了一個動作到動作集
    } else {
    // 新增一個動作到動作集失敗
    }
}];

想要執行一個動作集,可使用HMHome類的executeActionSet:completionHandler:方法。比如,使用者希望控制所有的節日彩燈。我們就建立一個動作集來開啟所有的節日彩燈,另外一個動作集來關閉所有的節日彩燈。為了開啟所有的節日彩燈,傳送executeActionSet:completionHandler:訊息給home物件,並傳遞"開啟節日彩燈"動作集。

建立並開啟觸發器

觸發器會執行一個或多個動作集。iOS會在後臺管理和執行你的觸發器。HMTrigger類是HMTimerTrigger具體類的抽象類。當你建立一個定時觸發器時,你需要指定觸發時間和觸發的週期。建立並開啟一個定時觸發器需要多個步驟來完成。

遵循下面幾步來建立並啟動一個定時觸發器

建立一個定時觸發器

1.建立定時觸發器。

self.trigger = [[HMTimerTrigger alloc] initWithName:name
fireDate:fireDate
timeZone:niL
recurrence:nil
recurrenceCalendar:nil];

2. 新增一個動作集到觸發器。

3. 新增一個觸發器到家庭。

4. 啟動觸發器。

一個定時觸發器被啟動後,會週期性的執行它的動作集。

第十部分:使用者管理

建立home的使用者是該home的管理員,可以執行所有操作,包括新增一個客人使用者到home。任何管理員新增到這個home的使用者(HMUser)都有一個有限的許可權。客人不能更改家庭的佈局,但是可以執行下面的動作:

  • 識別智慧電器

  • 讀寫特性

  • 觀察特性值變化

  • 執行動作集

比如,一個家庭的戶主可以建立一個home佈局並向其中新增家庭成員。每個家庭成員必須擁有一個iOS裝置和Apple ID以及相關的iCloud賬戶。iCloud需要個人輸入的Apple ID和戶主提供的Apple ID相吻合,以便讓他們訪問這個home。考慮到隱私問題,Apple ID對你的App是不可見的。

管理員需要遵從以下步驟來新增一個客人到home中:

1. 管理員