你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> HomeKit 開發指南(中文版)

HomeKit 開發指南(中文版)

編輯:IOS開發基礎

359516-products-that-need-apple-homekit.jpg

本文由CocoaChina翻譯組成員iBenjamin_Go和淺夏@舊時光翻譯自蘋果開發文檔:HomeKit Developer Guide,敬請勘誤。
本文檔內容包括

第一部分:簡介

第二部分:啟用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 User Interface Guidelines 提供了用戶界面設計指南

  • App Store Review Guidelines: HomeKit 提供了加快app審核的技巧

  • HomeKit Framework Reference 描述了HomeKit框架中的類和方法

  • External Accessory Framework Reference 列出了系統提供的發現和配置無線智能家居產品UI

  • HomeKit Catalog 提供示例演示HomeKit特性

  • WWDC 2014: Introducing HomeKit 對HomeKit更高層次的分析

  • iOS Security 描述HomeKit如何處理iOS上的安全和隱私

第二部分:啟用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 .

60.png

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

61.png

解決代碼簽名和證書配置問題,請參閱 App Distribution Guide文檔中Troubleshooting這一節。


啟用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對象的變化,請參閱:Observing HomeKit Database Changes。查閱異步消息完成處理後傳過來的錯誤碼的信息,請參閱:HomeKit Constants Reference.

對象命名規則

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

  • 對象名字在其命名空間內必須是唯一的。

  • 屬於用戶所有的home名字都在一個命名空間內。

  • 一個home對象及其所包含的對象在另一個命名空間內。

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

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

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

  • 名字沒有大小寫之分。

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

創建Homes

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

在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語句中,寫入代碼更新應用程序的視圖。

發現配件

Accessories封裝了物理配件的狀態,因此它不能被用戶創建。想要允許用戶給家添加新的配件,我們可以使HMAccessoryBrowser對象找到一個與home沒有關聯的配件。HMAccessoryBrower對象在後台搜尋配件,當它找到配件的時候,使用委托來通知你的應用程序。只有在startSearchingForNewAccessories方法調用之後或者stopSearchingForNewAccessories方法調用之前,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:方法。 當然也可以實現accessoryBrowser:didRemoveNewAccessory: 這個方法來移除配件,這個配件對你的視圖或者收藏來說不再是新的。

5. 停止搜尋配件

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

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

注意: 在WiFi網絡環境下,為了安全地獲取新的並且能夠被HomeKit發現的無線配件,請參閱External Accessory Framework Reference.

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

配件可提供一項或者多項服務,這些服務的特性是由制造商定義。想了解配件的服務和特性目的,請參閱 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交流。例如一個橋接口可以是控制多個燈的樞紐,它使用的是自己的通信協議,而不是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
}
}];

可使用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
} }];

第五部分:觀察HomeKit數據庫的變化

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

101.png

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的所有視圖。

102.png

應用程序只有在前台運行的時候才能接受代理消息。當你的應用在後台時,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;

3.實現HMHomeDelegate協議

例如:實現home:didAddAccessory:和home:didRemoveAccessory: 方法來更新展示配件的視圖。用HMAccessory類的room屬性可以獲得配件所屬的room。(對配件來說,默認的room是roomForEntireHome這個方法的返回值。)

Bridge Note:當你為home添加橋接口時,橋接口底層的配件會自動被添加到home中。你的代理會接收到橋接口後每個配件的 home:didAddAccessory:消息,但是你的代理不會接收到橋接口的home:didAddAccessory:消息。

觀察配件的變化

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

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

觀察個別配件的變化

  1. 在類接口中添加配件代理協議。

@interface AccessoryViewController ()  
@end

2. 設置配件的代理

accessory.delegate = self;

3. 實現 HMAccessoryDelegate 協議

比如,執行accessoryDidUpdateReachability:方法以啟用或者禁用配件控制。

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

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

accessoryDidUpdateServices:

accessory:service:didUpdateValueForCharacteristic:

想了解配件的服務,請參閱Accessing Services and Their Characteristics.

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

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

獲得配件的服務和屬性

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

重要:不要暴露匿名服務-比如固件升級服務-給用戶

通過HMAccessory類對象的services屬性,我們可以獲得一個配件的服務。

NSArray *services = accessroy.services;

要獲得一個home當中配件提供的特定服務,使用HMHome類對象的servicesWithTypes:方法。

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

使用HMServices類對象的name屬性來獲得服務的名稱

NSString *name = services.name;

要獲得一個服務的特性,請使用characteristics屬性。

NSArray *characteristics = service.characteristics

使用servicesType屬性來獲得服務的類型

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。

使用readValueWithCompletionHandler:異步方法來讀取一個特性的值。

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

在if語句塊中,加入你的代碼以更新app的視圖。

使用writeValue:completionHandler:異步方法來向一個特性寫入值。

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

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

另外,在別的app更新了特性的值時也需要更新視圖,在Observing Changes to Accessories中有描述。

創建服務組

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

405.png

在你創建了一個HMHome對象之後,如Getting the Primary Home and Collection of Homes中描述,你也就在這個家中創建一個服務組。

為了創建一個服務組,我們使用HMHome類對象的addServiceGroupWithName:completionHandler:方法。方法中參數服務組的名稱必須在此家中唯一,並可以被Siri識別。

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

我們使用HMServiceGroup類對象的addService:completionHandler:方法來向服務組中添加一個服務。服務可以在一個或多個服務組中。

[serviceGroup addService:service completionHandler:^(NSError *error) {
    if (error == nil) {
       // Successfully added service to service group
    }
       // Unable to add the service to the service group
    }];

通過HMHome類對象的serviceGroups屬性,來獲得這個家的所有服務組。

NSArray *serviceGroups = self.home.serviceGroups;

通過HMServiceGroup類對象的accessory屬性,我們獲得服務所對應的智能電器。

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. 輸入智能電器的名字和制造商。

QQ截圖20150326143608.png

4.  點擊完成

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

向智能電器(配件)中添加服務

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

按照下面步驟向智能電器中添加服務

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

該配件的服務信息會展示在一個詳情界面中。

066.png

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

2.  點擊添加服務(Add Service),並從彈出視圖中選擇一個服務類型。

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

63.png

向服務中添加特性

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

按照下面的步驟向服務中添加特性:

  1. 在HomeKit Accessory Simulator中,服務詳情視圖,點擊添加特性(Add Characteristic)

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

  3. 在其他文本框中輸入此特性的其他信息,並點擊完成(Finish).新添加的特性會在詳細視圖展示出來。

64.png

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

通過你的app向家庭中添加智能電器(配件)

在你通過HomeKit Accessory Simulator創建了一個智能電器後,運行你的App然後添加一個新的智能電器到你的家庭。

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

1.  在Xcode中,點擊Run並調用addAccessory:completionHandler:方法(如Adding Accessories to Homes and Rooms中描述的那樣).

2.  如果彈出了一個Add HomeKit Accessory對話框聲明這個智能電器未被信任(這在HomeKit Accessory Simulator中是被允許的),不用管它,點擊Add Anyway。

55.png

3.  在接下來顯示的Add HomeKit Accessory對話框中,輸入智能電器的setup code然後點擊Add。

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

65.png

關於如何編寫代碼來添加一個智能電器到家庭和房間請閱讀Creating Homes and Adding Accessoris。

控制智能電器(配件)

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

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

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

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

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

66.png

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

為了觀察HomeKit數據庫的變化,請閱讀Observing HomeKit Database Changes。如果你想從app中通過編寫代碼來控制一個智能電器,請閱讀Accessing Services and Characteristics。

添加橋接口

為了模擬那些不支持HomeKit Accessory Protocol協議的智能電器,需要添加一個虛擬橋接口,然後將智能電器添加到這個虛擬橋接口。配置虛擬橋接口底層的智能電器和配置其他類型的智能電器差不多。

添加一個虛擬橋接口到網絡

添加一個代表這個虛擬橋接口的智能電器。

為了添加一個虛擬橋接口到網絡你需要:

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

2.  在彈出框中選擇Add 虛擬橋接口。

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

88.png

4.  點擊完成

向虛擬橋接口添加智能電器配件
可向一個虛擬橋接口添加一個或多個智能電器。

為了向一個虛擬橋接口添加一個智能電器,需要:

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

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

  3. 輸入一個智能電器名字和制造商。

  4. 點擊完成。

想要了解虛擬橋接口中的智能電器的詳細信息,請選擇虛擬橋接口部分中的智能電器。如果需要的話你可以點擊虛擬橋接口旁邊的查看詳情來查看這個虛擬橋接口的智能電器。在你添加了一個服務和特性到這些智能電器之後,如Adding Services to Accessories和Adding Characteristics to Services中描述。它們會在這個虛擬橋接口被選擇之後被展示出來。

68.png

在你的App中添加虛擬橋接口到home

將虛擬橋接口和home匹配的過程和將一個智能電器配置到一個home的過程是一樣的,如Adding Accessories to a Home in Your App描述的。在虛擬橋接口底層的智能電器配件也一樣被加入到了home,如 Adding Bridges to Homes and Rooms所描述。

控制虛擬橋接口底層的智能電器

如何控制虛擬橋接口底層的智能電器和直接控制智能電器的步驟一致,如Controlling Accessories in HomeKit Accessory Simulator中描述,除了你直接選擇虛擬橋接口下的智能電器之外。

在多設備和多用戶環境中測試

在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識別。

69.png

創建寫入動作

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

為了創建一個動作,我們使用HMCharacteristicWriteAction類中的initWithCharacteristic:targetValue:方法。

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

在你的代碼中,你使用對應的特性的期望來替換value參數,並使用對應的HMCharacteristic對象來替換characteristic參數。

創建並執行動作集

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

為了創建一個動作集我們使用addActionSetWithName:completionHandler:異步方法。

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

為了添加一個動作到動作集,我們使用addAction:completionHandler:異步方法。

[actionSet addAction:action completionHandler:^(NSError *error) {
    if (error == nil) {
        // 成功添加了一個動作到動作集
    } else {
    // 添加一個動作到動作集失敗
    }
}];

想要移除一個動作,可使用removeAction:completionHandler:方法。

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

創建並開啟觸發器

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

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

創建一個定時觸發器

1.創建定時觸發器。

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

觸發時間必須設置在將來的某個時刻,第二個參數必須為0.如果你設置了一個周期,周期的最小值是5分鐘,最大值是5周。關於如何使用NSDateComponents和NSCalendar來設置周期,請閱讀Date and Time Programming Guide

2. 添加一個動作集到觸發器。

使用HMTrigger基類方法addActionSet:completionHandler:,來添加一個動作集到觸發器。

3. 添加一個觸發器到家庭。

使用HMHome類中的addTrigger:completionHandler:方法來添加一個觸發器到家庭。

4. 啟動觸發器。

新創建的觸發器默認是未啟動的。需要使用enable:complationHandler:方法啟動觸發器。

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

第十部分:用戶管理

創建home的用戶是該home的管理員,可以執行所有操作,包括添加一個客人用戶到home。任何管理員添加到這個home的用戶(HMUser)都有一個有限的權限。客人不能更改家庭的布局,但是可以執行下面的動作:

  • 識別智能電器

  • 讀寫特性

  • 觀察特性值變化

  • 執行動作集

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

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

1. 管理員調用一個動作將客人添加到home中。

2. 你的App調用addUserWithCompletionHandler:異步方法。

3. HomeKit展示一個對話框,要求輸入客人的Apple ID。

4. 用戶輸入客人的Apple ID。

5. 在完成回調中返回一個新的用戶。

6. 你的App展示客人的名字。

添加一個客人到home,需要在客人的iOS設備上做以下操作:

1. 用戶在iCloud偏好設置中輸入iCloud憑證(Apple ID和密碼)。

2. 用戶啟動你的App。

3. 你的App通過home manager object獲得一個home集合。

4. 如果iCloud的憑證和管理員輸入的Apple ID相同,那麼管理員的home將會出現在homes屬性中。

客人執行的操作可能會失敗。如果一個異步方法中出現HMErrorCodeInsufficientPrivileges錯誤碼的話,這就意味著用戶沒有足夠的權限來執行動作-也許這個用戶只是客人,而不是管理員。

為了測試你的App是否正確處理了客人用戶,請閱讀Testting Multiple iOS Devices and Users。

添加和移除用戶

為了添加一個客人用戶到home,請使用addUserWithCompletionHandler:異步方法。

[self.home addUserWithCompletionHandler:^(HMUser *user, NSError *error) {
    if (error == nil) {
        // Successfully added a user
    }
    else {
       // Unable to add a user
} }];

想要移除home中的用戶,請使用HMHome類的removeUser:completionHandler:方法。

通過實現HMHomeDelegate協議中的home:didAddUser:和home:didRemoveUser:協議方法檢查新添加和移除的用戶並更新視圖。關於如何創建一個delegate,請閱讀Observing Changes to Individual Homes。

獲得用戶名

出於隱私的考慮,你的app對用戶名只有讀得權限,並不能讀寫用戶的Apple ID。使用HMHome對象的users屬性來獲取用戶。使用HMUser類的name屬性來獲取用戶名。

轉載請出名出處和鏈接

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved