Creating Homes and Adding Accessories

HomeKit objects are stored in a shared HomeKit database accessed by multiple apps through the HomeKit framework. All HomeKit method calls that write records are asynchronous and contain a completion handler parameter. If the method is successful, your app should update local objects in the completion handler. The app that initiates the change to HomeKit objects doesn’t receive delegate messages; the app only receives completion handler callbacks.

To observe changes to HomeKit objects initiated by other apps, read Observing HomeKit Database Changes. For the error codes that may be passed to completion handlers of asynchronous messages, read HomeKit Constants Reference.

Rules for Naming Objects

The names of HomeKit objects—such as home, room, and zone objects—are recognized by Siri where indicated in this document. The following rules apply to setting names of HomeKit objects:

To learn about the language the user can use to interact with Siri, read “Siri Integration” in HomeKit User Interface Guidelines.

Creating Homes

To add a home, use the addHomeWithName:completionHandler: asynchronous method in the HMHomeManager class. The home name, passed as a parameter to this method, must be unique. Home names are recognized by Siri.

    [self.homeManager addHomeWithName:@"My Home" completionHandler:^(HMHome *home, NSError *error) {
        if (error != nil) {
            // Failed to add a home
        } else {
            // Successfully added a home
        }
    }];

In the else clause, insert your code that updates the app’s views. To get the home manager, read Getting the Home Manager Object.

Adding a Room to a Home

To add a room to a home, use the addRoomWithName:completionHandler: asynchronous method. The room name, passed as a parameter to this method, must be unique within the home. Room names are recognized by Siri.

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

In the else clause, insert your code that updates the app’s views.

Discovering Accessories

Accessories encapsulate the state of a physical accessory and therefore cannot be created by the user. To allow users to add new accessories to their home, use an HMAccessoryBrowser object to discover new accessories not yet associated with a home. The HMAccessoryBrowser object searches for accessories in the background and uses delegation to notify your app when it finds new accessories. The HMAccessoryBrowserDelegate messages are sent to the delegate only after the startSearchingForNewAccessories method is invoked and before the stopSearchingForNewAccessories method is invoked.

To discover accessories in a home

  1. Add the accessory browser delegate protocol, and add an accessory browser property to your class interface.

    @interface EditHomeViewController () <HMAccessoryBrowserDelegate>
     
    @property HMAccessoryBrowser *accessoryBrowser;
     
    @end

    Replace EditHomeViewController with your class name.

  2. Create the accessory browser object, and set its delegate.

    self.accessoryBrowser = [[HMAccessoryBrowser alloc] init];
    self.accessoryBrowser.delegate = self;
  3. Start searching for accessories.

    [self.accessoryBrowser startSearchingForNewAccessories];
  4. Add found accessories to your collection.

    - (void)accessoryBrowser:(HMAccessoryBrowser *)browser didFindNewAccessory:(HMAccessory *)accessory {
        // Update the UI per the new accessory; for example, reload a picker view.
        [self.accessoryPicker reloadAllComponents];
    }

    Replace the above accessoryBrowser:didFindNewAccessory: implementation with your code. Also, implement the accessoryBrowser:didRemoveNewAccessory: method to remove an accessory that is no longer new from your collection or view.

  5. Stop searching for accessories.

    If a view controller starts looking for accessories, override viewWillDisappear: to stop looking for accessories.

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

Adding Accessories to Homes and Rooms

Accessories belong to a home and optionally can be added to a room in a home. To add an accessory to a home, use the addAccessory:completionHandler: asynchronous method. The accessory name, passed as a parameter to this method, must be unique within a home. To add an accessory to a room in a home, use the assignAccessory:toRoom:completionHandler: asynchronous method. The default room for an accessory is the room returned by the roomForEntireHome method.

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

Accessories have one or more services, and services have characteristics defined by manufacturers. To get service and characteristic objects from an accessory, read Accessing Services and Characteristics.

Changing Names of Accessories

To change the name of an accessory, use the updateName:completionHandler: asynchronous method.

[accessory updateName:@"Kid's Night Light" completionHandler:^(NSError *error) {
    if (error) {
        // Failed to change the name
    } else {
        // Successfully changed the name
    }
}];

Adding Bridges to Homes and Rooms

A bridge is a special type of accessory that allows you to communicate with accessories that can’t communicate directly with HomeKit. For example, a bridge might be a hub for multiple lights that use a communication protocol other than HomeKit Accessory Protocol. To add a bridge to a home, follow the steps for adding any other type of accessory to a home, as described in Adding Accessories to Homes and Rooms. When you add a bridge to a home, the accessories behind the bridge are also added to the home. Per the change notification design pattern, described in Observing HomeKit Database Changes, the home’s delegate won’t receive a home:didAddAccessory: delegate message for the bridge, but will receive a home:didAddAccessory: delegate message for each accessory behind the bridge. Treat the accessories behind a bridge in the same way as any other accessory in a home—for example, add them to the list of configured accessories.

In contrast, when you add a bridge to a room, the accessories behind the bridge are not automatically added to the room because the bridge and its accessories can be located in different rooms.

Creating Zones

A zone (HMZone) is an arbitrary optional grouping of rooms; for example, upstairs, downstairs, or bedrooms. Rooms can be added to one or more zones.

../Art/zones_2x.png

To create a zone, use the addZoneWithName:completionHandler: asynchronous method. The name of the zone, passed as an argument to this method, must be unique within a home. Zone names are recognized by 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
    }
}];

To add a room to a zone, use the addRoom:completionHandler: asynchronous method.

__block HMRoom *room = roomInHome;
[zone addRoom:room completionHandler:^(NSError *error) {
    if (error) {
        // Failed to add room to zone
    } else {
        // Successfully added room to zone
    }
}];