ホームの生成、アクセサリの追加

HomeKitオブジェクトは共有HomeKitデータベースに格納されており、HomeKitフレームワークを介して、さまざまなアプリケーションからアクセスできます。レコードを書き込むHomeKitのメソッド呼び出しはすべて非同期型であり、完了ハンドラをパラメータとして渡すようになっています。完了ハンドラには、メソッドの処理が正常終了したときに、ローカルオブジェクトを更新する処理を記述してください。アプリケーションがHomeKitオブジェクトに変更を施しても、デリゲートメッセージとして通知されることはなく、完了ハンドラがコールバックとして呼び出されるだけです。

他のアプリケーションがHomeKitオブジェクトに対して施した変更を監視する方法については、「HomeKitデータベースの変更監視」を参照してください。非同期型メッセージの完了ハンドラに渡されるエラーコードは、『HomeKit Constants Reference』に一覧が載っています。

オブジェクトの名前づけ規約

以下、関係する箇所で説明するように、SiriはHomeKitのオブジェクト(ホーム、ルーム、ゾーンなど)の名前を認識します。HomeKitオブジェクトの名前は、次の規約に従って与えてください。

Siriとやり取りするための言語については、「HomeKit User Interface Guidelines」の「Siri Integration」を参照してください。

ホームを生成する

ホームの追加はHMHomeManagerクラスのaddHomeWithName:completionHandler:メソッド(非同期型)でおこないます。パラメータとして渡すホームの名前は、一意でなければなりません。これはSiriが認識する名前になります。

    [self.homeManager addHomeWithName:@"My Home" completionHandler:^(HMHome *home, NSError *error) {
        if (error ! = nil) {
            // ホームの追加に失敗
        } else {
            // ホームを正常に追加完了
        }
    }];

else以下に、アプリケーションのビューを更新するコードを記述してください。ホームマネージャを取得する手順については、「ホームマネージャオブジェクトを取得する」を参照してください。

ルームをホームに追加する

ルームをホームに追加するにはaddRoomWithName:completionHandler:メソッド(非同期型)を使います。パラメータとして渡すルームの名前は、ホーム内で一意でなければなりません。これはSiriが認識する名前になります。

    NSString *roomName = @"Living Room";
    [home addRoomWithName:roomName completionHandler:^(HMRoom *room, NSError *error) {
        if (error ! = nil) {
            // ルームへのホームの追加に失敗
        } else {
            // ルームへのホームの追加が正常に完了
        }
    }];

else以下に、アプリケーションのビューを更新するコードを記述してください。

アクセサリを検出する

アクセサリは、実物のアクセサリの状態をカプセル化して管理するものであり、ユーザ側で生成することはできません。ユーザがホームに、新規にアクセサリを追加できるようにするため、HMAccessoryBrowserオブジェクトを使って、まだホームに関連づけられていないアクセサリを検出します。HMAccessoryBrowserオブジェクトはバックグラウンド処理でアクセサリを検索し、見つかると、デリゲートの機構を使ってアプリケーションに通知します。HMAccessoryBrowserDelegateメッセージがデリゲートに送出されるのは、startSearchingForNewAccessoriesメソッドを呼び出してから、stopSearchingForNewAccessoriesメソッドを呼び出すまでの間に限ります。

ホーム内のアクセサリを検出するには

  1. 「アクセサリブラウザ(Accessory Browser)」のデリゲートプロトコルおよびプロパティを、クラスインターフェイスに追加してください。

    @interface EditHomeViewController () <HMAccessoryBrowserDelegate>
     
    @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 {
        // 新しいアクセサリに従ってUIを更新(ピッカービューの再読み込みなど)
        [self.accessoryPicker reloadAllComponents];
    }

    上記のaccessoryBrowser:didFindNewAccessory:の実装を、実際のアプリケーションに合わせて置き換えてください。さらに、新規ではなくなったアクセサリをコレクションやビューから削除する、accessoryBrowser:didRemoveNewAccessory:メソッドも実装します。

  5. アクセサリの検索を停止します。

    ビューコントローラがアクセサリの検索処理を起動する場合、検索を停止するようviewWillDisappear:をオーバーライドしてください。

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

アクセサリをホームやルームに追加する

アクセサリはホームに属するほか、そのホーム内のルームに追加することも可能です。アクセサリをホームに追加するには、addAccessory:completionHandler:メソッド(非同期型)を使います。パラメータとして渡すアクセサリの名前は、ホーム内で一意でなければなりません。アクセサリをホーム内のルームに追加するには、assignAccessory:toRoom:completionHandler:メソッド(非同期)を使います。アクセサリを追加する「デフォルトの」ルームとは、roomForEntireHomeメソッドの戻り値として得られるルームのことです。

// アクセサリをホームとルームに追加
// 1. 完了ハンドラ用にホームオブジェクトとルームオブジェクトを取得
__block HMHome *home = self.home;
__block HMRoom *room = roomInHome;
 
// 2. アクセサリをホームに追加
[home addAccessory:accessory completionHandler:^(NSError *error) {
    if (error) {
        // ホームへのアクセサリの追加に失敗
    } else {
        if (accessory.room ! = ルーム) {
            // 3. 処理が正常に完了した場合は、アクセサリをルームに追加
            [home assignAccessory:accessory toRoom:room completionHandler:^(NSError *error) {
                if (error) {
                    // ルームへのアクセサリの追加に失敗
                }
            }];
        }
    }
}];

アクセサリにはいくつかのサービスが属し、サービスには製造元が定義したキャラクタがあります。アクセサリのサービスやキャラクタオブジェクトを取得する手順については、「サービスおよびそのキャラクタに対するアクセス」を参照してください。

アクセサリ名を変更する

アクセサリ名の変更にはupdateName:completionHandler:メソッド(非同期型)を使います。

[accessory updateName:@"Kid's Night Light" completionHandler:^(NSError *error) {
    if (error) {
        // 名前の変更が失敗
    } else {
        // 名前の変更が正常に完了
    }
}];

ホームやルームにブリッジを追加する

ブリッジとは特殊なアクセサリで、HomeKitと直接は通信できないアクセサリとの間で、通信を中継する働きがあります。たとえば、HomeKit Accessory Protocolとは異なるプロトコルで通信する、いくつもの照明器具をつないだ「ハブ」がこれに当たります。ブリッジをホームに追加する手順は、一般のアクセサリの場合と同じです(「アクセサリをホームやルームに追加する」を参照)。ブリッジをホームに追加すれば、その先にあるアクセサリもホームに追加したことになります。「変更の通知」デザインパターン(「HomeKitデータベースの変更監視」を参照)に従って実装した場合、ホームのデリゲートが受け取るhome:didAddAccessory:デリゲートメッセージは、ブリッジではなく、その先にある各アクセサリを追加した旨を表すものになります。ブリッジの先にあるアクセサリについても、設定済みアクセサリのリストに追加するなど、そうでないアクセサリと同様に扱ってください。

一方、ブリッジを(ホームではなく)ルームに追加した場合、その先にあるアクセサリが、自動的にルームに追加されることはありません。ブリッジとアクセサリが別々のルームにあるかも知れないからです。

ゾーンを生成する

「ゾーン(Zone)」(HMZone)とは、いくつかのルームをグループ化したもので、「2階のルーム」、「1階のルーム」、「寝室群」などが考えられます。同じルームを複数のゾーンに入れても構いません。

../Art/zones_2x.png

ゾーンの生成にはaddZoneWithName:completionHandler:メソッド(非同期型)を使います。引数として渡すゾーンの名前は、ホーム内で一意でなければなりません。これはSiriが認識する名前になります。

__block HMHome *home = self.home;
NSString *zoneName = @"Upstairs";
[home addZoneWithName:zoneName completionHandler:^(HMZone *zone, NSError *error) {
    if (error) {
        // ゾーンの作成に失敗
    } else {
        // ゾーンの作成が正常に完了し、ルームを追加
    }
}];

ルームをゾーンに追加するにはaddRoom:completionHandler:メソッド(非同期型)を使います。

__block HMRoom *room = roomInHome;
[zone addRoom:room completionHandler:^(NSError *error) {
    if (error) {
        // ゾーンへのルームの追加に失敗
    } else {
        // ゾーンへのルームの追加が正常に完了
    }
}];