HomeKit Developer Guide Contents Introduction to HomeKit 4 See Also 5 Enabling HomeKit 6 Setup 6 Enable HomeKit 7 Download HomeKit Accessory Simulator 7 Getting the Home Layout 9 Getting the Home Manager Object 10 Getting the Primary Home and Collection of Homes 10 Getting the Rooms in a Home 11 Getting the Accessories in a Room 11 Getting Accessories in a Home 11 Creating Homes and Adding Accessories 12 Rules for Naming Objects 12 Creating Homes 13 Adding a Room to a Home 13 Discovering Accessories 14 Adding Accessories to Homes and Rooms 15 Changing Names of Accessories 16 Adding Bridges to Homes and Rooms 16 Creating Zones 17 Observing HomeKit Database Changes 19 About HomeKit Delegation Methods 19 Observing Changes to the Collection of Homes 20 Observing Changes to Individual Homes 22 Observing Changes to Accessories 23 Accessing Services and Characteristics 25 Getting Services and Their Properties 25 Changing Names of Services 26 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 2 Contents Accessing Values of Characteristics 27 Creating Service Groups 28 Testing Your HomeKit App 30 Adding Accessories 30 Adding Services to Accessories 31 Adding Characteristics to Services 33 Adding Accessories to a Home in Your App 34 Controlling Accessories 35 Adding Bridges 36 Adding a Bridge to the Network 36 Adding Accessories Behind a Bridge 37 Adding Bridges to a Home in Your App 38 Controlling Accessories Behind a Bridge 38 Testing Multiple iOS Devices and Users 39 Creating Action Sets and Triggers 40 Creating Write Actions 40 Creating and Executing Action Sets 41 Creating and Enabling Timer Triggers 42 Managing Users 43 Adding and Removing Users 44 Getting User Names 44 Document Revision History 45 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 3 Introduction to HomeKit This document helps you write a HomeKit app. HomeKit is a framework for communicating with and controlling connected home automation accessories that support Apple's HomeKit Accessory Protocol. HomeKit apps enable users to discover compatible accessories and configure them. Users can also create actions to control accessories (such as a thermostat or light), group them together, and trigger them by using Siri. HomeKit objects are stored in a database residing on the user’s iOS device, which is synchronized over iCloud to other iOS devices. HomeKit supports remote access to accessories, multiple user devices, and multiple users. HomeKit also handles security and privacy for you. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 4 Introduction to HomeKit See Also Note: If you’re a vendor who is creating a HomeKit-enabled hardware accessory, go to the HomeKit page under Hardware Developers, for information about the MFi Program. Also read External Accessory Programming Topics . See Also The following resources provide more information about creating a HomeKit app: ● HomeKit User Interface Guidelines provides guidelines for designing the user interface for your app. ● App Store Review Guidelines: HomeKit gives you tips for accelerating the approval process when you submit your app. ● HomeKit Framework Reference describes the classes and methods in the HomeKit framework. ● External Accessory Framework Reference documents the system-provided UI for discovering and configuring wireless accessories without requiring the user to leave your app. ● HomeKit Catalog sample code demonstrates HomeKit features. ● WWDC 2014: Introducing HomeKit is a high-level look at HomeKit. ● iOS Security describes how HomeKit handles security and privacy on iOS. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 5 Enabling HomeKit HomeKit is an app service available only to apps distributed through the App Store. HomeKit requires additional configuration in your Xcode project. Your app must be provisioned and code signed to use HomeKit. To avoid code signing issues, enable HomeKit in the Xcode Capabilities pane. You don’t need to edit entitlements directly in Xcode or Member Center. Setup To perform all the steps in this document, you need: ● A Mac computer with Xcode 6 or later installed ● For the best experience, the latest OS X and Xcode releases installed on your Mac ● Membership in the iOS Developer Program ● Permission to create code signing and provisioning assets in Member Center Verify that you have performed these tasks before you begin using HomeKit. To create your team provisioning profile, read App Distribution Quick Start . Task Join the iOS Developer Program. Create an Xcode project that builds and runs. Add your Apple ID to Accounts preferences. In the General pane, create your team provisioning profile: ● Choose your team from the Team pop-up menu. ● Click Fix Issue. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 6 Enabling HomeKit Enable HomeKit When you successfully complete the preceding tasks, the error message and the Fix Issue button below the Team pop-up menu in the General pane disappear. The screenshot below shows the General pane when the code signing assets are successfully created. To troubleshoot code signing and provisioning, read Troubleshooting in App Distribution Guide . Enable HomeKit To use HomeKit, you first enable it. Xcode will add the HomeKit entitlement to your entitlements file in the project and App ID in Member Center. Xcode also adds the HomeKit framework to your project. HomeKit requires an explicit App ID, which is created for you when you complete these steps. To enable HomeKit 1. In Xcode, choose View > Navigators > Show Project Navigator. 2. Choose the target from the Project/Targets pop-up menu (or in the Product/Targets sidebar if it appears). 3. Click Capabilities to view app services that you can add to your app. 4. Scroll down to the HomeKit row and select the switch. Download HomeKit Accessory Simulator You don’t need to buy accessories to develop your HomeKit app. You can use HomeKit Accessory Simulator to test the communication of your HomeKit app with simulated accessories. HomeKit Accessory Simulator is not distributed with Xcode. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 7 Enabling HomeKit Download HomeKit Accessory Simulator To download HomeKit Accessory Simulator 1. In the HomeKit section of the Capabilities pane, click Download HomeKit Accessory Simulator. Alternatively, choose Xcode > Open Developer Tool > More Developer Tools. 2. In a browser, search for and download the “Hardware IO Tools for Xcode” .dmg file. 3. In the Finder, double-click the .dmg file in ~/Downloads. 4. Drag HomeKit Accessory Simulator to the /Applications folder. Later, you’ll test your app using HomeKit Accessory Simulator, as described in Testing Your HomeKit App (page 30). 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 8 Getting the Home Layout HomeKit allows users to create a layout for one or more of their homes. A home (HMHome) represents a single dwelling that has a network of accessories. A home’s data is owned by the user and can be accessed from any of the user’s iOS devices. A user can also share a home with a guest who has more limited access. One home is designated as the primary home and is the default home for Siri commands that don’t specify a home. Each home may have multiple rooms and accessories added to each room. A room (HMRoom) represents an individual room in the home. It has a meaningful name, such as “living room” or “kitchen," which can be used in Siri commands. An accessory (HMAccessory) is a physical home automation device, such as a garage door opener. A service (HMService) is an actual service provided by an accessory, such as opening and closing a garage door or the light on the garage door opener. If your app caches information about a home’s layout, it needs to update that information when the home layout changes. Use a HMHomeManager object to fetch HMHome and related objects from the HomeKit database. After fetching objects using the APIs described in this chapter, keep your objects synchronized with the database through delegate callbacks, as described in Observing HomeKit Database Changes (page 19). 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 9 Getting the Home Layout Getting the Home Manager Object Getting the Home Manager Object Use the home manager, an HMHomeManager object, to access home, room, accessory, service, and other HomeKit objects. Immediately after creating the home manager, set its delegate so that you are notified when the initial fetch of these objects is complete. self.homeManager = [[HMHomeManager alloc] init]; self.homeManager.delegate = self; When you create a home manager object, HomeKit begins fetching the homes and associated objects—for example, room and accessory objects—from the HomeKit database. While HomeKit is fetching these objects, the value for the home manager primaryHome property is nil, and homes property is an empty array. Your app should handle the case in which the user hasn’t created a home yet, but the app should not behave as if there are no homes until HomeKit completes the initial fetch. HomeKit sends the homeManagerDidUpdateHomes: message to the home manager’s delegate when the fetch is complete. Note: The homeManagerDidUpdateHomes: method is also invoked when the app comes to the foreground and changes occurred while it was in the background, as described in Observing Changes to the Collection of Homes (page 20). Getting the Primary Home and Collection of Homes To get the primary home, use the primaryHome property of the home manager. HMHome *home = self.homeManager.primaryHome; Use the home manager homes property to get all of the user’s homes; for example, a primary residence, a vacation home, and an office. Each home is represented by a separate home object. HMHome *home; for (home in self.homeManager.homes){ … } 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 10 Getting the Home Layout Getting the Rooms in a Home Getting the Rooms in a Home Rooms define physical locations of accessories within a home. To enumerate the rooms in a home, use the home’s rooms property. HMHome *home = self.homeManager.primaryHome; HMHome *room; for (room in home.rooms){ … } Getting the Accessories in a Room Accessories belong to a home but are assigned to a room in a home. If the user doesn’t assign an accessory to a room, the accessory is assigned to the default room returned by the roomForEntireHome method. To enumerate the accessories in a room, use the room’s accessories property. HMAccessory *accessory; for (accessory in room.accessories){ … } If you display information about an accessory or allow the user to control an accessory, set the accessory’s delegate and implement accessory delegate methods, as described in Observing Changes to Accessories (page 23). Once you have an accessory object, you can access its services and their characteristics, as described in Accessing Services and Characteristics (page 25). Getting Accessories in a Home To get all accessories directly from the home object without enumerating rooms in a home (as described in Getting the Accessories in a Room (page 11)), use the accessories method in the HMHome class. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 11 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 (page 19). 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: ● Names must be unique within their namespace. ● The names of homes belonging to a user are in one namespace. ● A home object and its containing objects are in another namespace. ● A name can contain only alphanumeric, space, and apostrophe characters. ● A name must start with an alphabetic or numeric character. ● Space and apostrophe characters are ignored in comparisons (for example, home1 and home 1 are the same). ● A name is not case-sensitive. To learn about the language the user can use to interact with Siri, read “Siri Integration” in HomeKit User Interface Guidelines. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 12 Creating Homes and Adding Accessories Creating Homes 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 (page 10). 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. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 13 Creating Homes and Adding Accessories Discovering Accessories 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]; } 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 14 Creating Homes and Adding Accessories Adding Accessories to Homes and Rooms 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]; } Note: To get a new wireless accessory on the Wi-Fi network securely so it can be discovered by HomeKit, read External Accessory Framework Reference . 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 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 15 Creating Homes and Adding Accessories Changing Names of Accessories [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 (page 25). 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 (page 15). 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 (page 19), the home’s delegate won’t receive a home:didAddAccessory: delegate message for the bridge, but will receive a 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 16 Creating Homes and Adding Accessories Creating Zones 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. 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 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 17 Creating Homes and Adding Accessories Creating Zones } }]; 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 } }]; 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 18 Observing HomeKit Database Changes There is one HomeKit database per home. As shown in the figure below, the database is securely synchronized with a user’s iOS devices and potentially with guest user iOS devices that are granted access to the home. In order to show the most current data to the user, your app needs to observe changes to this database. About HomeKit Delegation Methods HomeKit using the delegation design pattern in Cocoa Core Competencies ) to notify your app of changes to HomeKit objects. In general, if your app invokes a HomeKit method with a completion handler parameter and the method is successful, the associated delegate message is sent to other HomeKit apps running on the same or remote iOS devices. The apps can even be run by guest users on their iOS devices. If your app initiates the change, the delegate message is not sent to your app. Therefore, add code to both the completion handler and the associated delegate method to reload data and update views as needed. If a home layout changes 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 19 Observing HomeKit Database Changes Observing Changes to the Collection of Homes significantly, reload all the information about that home. In the case of the completion handler, check whether the method is successful before updating the app. HomeKit also invokes delegate methods to notify your app of changes to the state of the home network. For example, if (1) in response to a user action, (2) your app invokes addRoomWithName:completionHandler: and no error occurs, (3) the completion handler should (4) update the views of the home. If successful, HomeKit (5) sends the home:didAddRoom: message to delegates of the home in other apps. Therefore, your implementation of the home:didAddRoom: method should also (6) update the views of the home. The apps need to be in the foreground to receive these delegate messages. Changes are not batched while your app is in the background. If your app is in the background while another app successfully adds a room to a home, your app doesn’t receive a home:didAddRoom: message. When your app comes to the foreground, your app receives a homeManagerDidUpdateHomes: message, which signals your app to reload all its data. Observing Changes to the Collection of Homes To receive delegate messages when the primary home or collection of homes changes, set the home manager’s delegate and implement the HMHomeManagerDelegate protocol. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 20 Observing HomeKit Database Changes Observing Changes to the Collection of Homes All apps need to implement the homeManagerDidUpdateHomes: method, which is invoked after HomeKit finishes the initial fetch of homes. Until this method is invoked, for a newly created home manager, the primaryHome property is nil and the homes property is an empty array. The homeManagerDidUpdateHomes: method is also invoked when the app comes to the foreground, and changes occurred while it was in the background. The homeManagerDidUpdateHomes: method should reload all data associated with the homes. To observe changes to homes 1. Add the home manager delegate protocol and home manager property to your class interface. @interface AppDelegate () <HMHomeManagerDelegate> @property (strong, nonatomic) HMHomeManager *homeManager; @end 2. Create the home manager object and set its delegate. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.homeManager = [[HMHomeManager alloc] init]; self.homeManager.delegate = self; return YES; 3. Implement the delegate methods that are invoked when a home changes. For example, if multiple view controllers display information about homes, you can post a notification that a change occurred to update all the views. - (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 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 21 Observing HomeKit Database Changes Observing Changes to Individual Homes [[NSNotificationCenter defaultCenter] postNotificationName:@"UpdatePrimaryHomeNotification" object:self]; } View controllers register for the change notification and implement the appropriate action. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateHomes:) name:@"UpdateHomesNotification" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePrimaryHome:) name:@"UpdatePrimaryHomeNotification" object:nil]; Observing Changes to Individual Homes The view controller that displays information about a home should be the delegate for the home object and update its views when the home changes. To observe changes to a specific home 1. Add the home delegate protocol to your class interface. @interface HomeViewController () <HMHomeDelegate> @end 2. Set the delegate of the accessory. home.delegate = self; 3. Implement the HMHomeDelegate protocol. For example, implement the home:didAddAccessory: and home:didRemoveAccessory: methods to update views that display accessories. To get the room that the accessory belongs to, use the room property in the HMAccessory class. (The default room for an accessory is returned by the roomForEntireHome method.) 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 22 Observing HomeKit Database Changes Observing Changes to Accessories Bridge Note: When you add a bridge to a home, the accessories behind the bridge are automatically added to the home. Your delegate receives a home:didAddAccessory: message for each accessory behind the bridge, but your delegate doesn’t receive a home:didAddAccessory: message for the bridge. Observing Changes to Accessories The state of an accessory can change at any time. An accessory may not be reachable, can be out of range, or may be turned off. Update the user interface accordingly to reflect the current state of accessories, especially if your app allows the user to control an accessory. In these steps it is assumed that you already retrieved an accessory object from the HomeKit database, as described in Getting the Accessories in a Room (page 11). To observe changes to a specific accessory 1. Add the accessory delegate protocol to your class interface. @interface AccessoryViewController () <HMAccessoryDelegate> @end 2. Set the delegate of the accessory. accessory.delegate = self; 3. Implement the HMAccessoryDelegate protocol. For example, implement the accessoryDidUpdateReachability: method to enable or disable accessory controls. - (void)accessoryDidUpdateReachability:(HMAccessory *)accessory { if (accessory.reachable == YES) { // Can communicate with the accessory } else { // The accessory is out of range, turned off, etc } } 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 23 Observing HomeKit Database Changes Observing Changes to Accessories If you display the state of services and their characteristics, implement the following delegate methods to update views accordingly: accessoryDidUpdateServices: accessory:service:didUpdateValueForCharacteristic: To access the services of an accessory, read Accessing Services and Their Characteristics (page 25). 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 24 Accessing Services and Characteristics A service (HMService) represents a function of an accessory and encapsulates characteristics (HMCharacteristic) that have read-write properties. An accessory can have multiple services, and a service can have multiple characteristics. For example, a garage opener accessory may have a light and switch service. The light service may have on/off and dimmer characteristics. Users don’t create accessories and their services—the manufacturer defines the functions of an accessory—but users may change the values of service characteristics. Some characteristics represent a physical state that has read and write properties—for example, the current temperature of a thermostat is read-only, but the target temperature is read-write. Apple provides predefined service and characteristic names that are recognized and understood by Siri. Getting Services and Their Properties After you get an accessory object, as described in Getting the Accessories in a Room (page 11), you can obtain information about its services and their characteristics. You can also get services by type directly from the home. Important: Don’t expose an unnamed service—such as a firmware update service—to the user. To get the services of an accessory, use the services property in the HMAccessory class. NSArray *services = accessory.services; To get services provided by accessories in a home that match specified types, use the servicesWithTypes: method in the HMHome class. // Get all lights and thermostats in a home NSArray *lightServices = [home servicesWithTypes:[HMServiceTypeLightbulb]]; NSArray *thermostatServices = [home servicesWithTypes:[HMServiceTypeThermostat]]; To get the name of a service, use the name property in the HMService class. NSString *name = service.name; 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 25 Accessing Services and Characteristics Changing Names of Services To get the characteristics of a service, use the characteristics property. NSArray *characteristics = service.characteristics; To get the type of service, use the serviceType property. NSString *serviceType = service.serviceType; Apple-defined service types that are recognized by Siri include: ● Door locks ● Garage door openers ● Lights ● Outlets ● Thermostats Changing Names of Services To change the name of a service, use the updateName:completionHandler: asynchronous method. The service name, passed as a parameter to this method, must be unique within a home. Service names are recognized by Siri. [service updateName:@"Garage 1 Opener" completionHandler:^(NSError *error) { if (error) { // Failed to change the name } else { // Successfully changed the name } }]; 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 26 Accessing Services and Characteristics Accessing Values of Characteristics Accessing Values of Characteristics A characteristic represents a parameter of a service that is either read-only, read-write, or write-only. It provides information about the possible values of the parameter, for example, a Boolean or range. The temperature of a thermostat is read-only, and the target temperature is read-write. A command that performs an action but requires no feedback—such as playing a sound or flashing a light to confirm the identity of an accessory—may be write-only. Apple-defined characteristic types that are recognized by Siri include: ● Brightness ● Current temperature ● Lock state ● Power state ● Target state ● Target temperature For example, the target state for a garage door opener is open or closed. The target state for a door lock is locked or unlocked. After you get an HMService object, as described in Getting Services and Their Properties (page 25), you can access the values of the individual service characteristics. Because the values are obtained from the physical accessory, these read and write methods are asynchronous with completion handler parameters. To read the value of a characteristic, use the readValueWithCompletionHandler: asynchronous method. [characteristic readValueWithCompletionHandler:^(NSError *error) { if (error == nil) { // Successfully read the value id value = characteristic.value; } else { // Unable to read the value } }]; In the if clause, insert your code that updates the app’s views. To write the value of a characteristic, use the writeValue:completionHandler: asynchronous method. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 27 Accessing Services and Characteristics Creating Service Groups [self.characteristic writeValue:@42 withCompletionHandler:^(NSError *error) { if (error == nil) { // Successfully wrote the value } else { // Unable to write the value } }]; Don’t assume the write method is successful until the completion handler is called with no error. For example, don’t change the state of a switch until the characteristic it represents changes state. In the if clause, insert your code that updates the app’s views. In addition, update views when other apps change the values of characteristics, as described in Observing Changes to Accessories (page 23). Creating Service Groups A service group (HMServiceGroup) provides a convenient way to control arbitrary services belonging to different accessories—for example, controlling a subset of lights in the home when the user is away. After you get a HMHome object, as described in Getting the Primary Home and Collection of Homes (page 10), you can create a service group within that home. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 28 Accessing Services and Characteristics Creating Service Groups To create a service group, use the addServiceGroupWithName:completionHandler: method in the HMHome class. The service group name, a parameter to this method, must be unique within a home. Service group names are recognized by 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 }]; To add a service to a service group, use the addService:completionHandler: method in the HMServiceGroup class. Services can be in one or more service groups. [serviceGroup addService:service completionHandler:^(NSError *error) { if (error == nil) { // Successfully added service to service group } // Unable to add the service to the service group }]; To get service groups for a home, use the serviceGroups property in the HMHome class. NSArray *serviceGroups = self.home.serviceGroups; To get the accessory for a service, use the accessory property in the HMServiceGroup class. HMAccessory *accessory = service.accessory; Similar to accessories, delegate methods are invoked when other apps change service groups. If your app uses service groups, read HMHomeDelegate Protocol Reference for the methods you should implement to observe these changes. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 29 Testing Your HomeKit App If you don’t have physical accessories, use HomeKit Accessory Simulator to simulate accessories in a home. Each simulated accessory has services with characteristics that you can control from your app. Your app creates the objects and relationships that are stored in the HomeKit database. It creates the home layout, adds new accessories to the home in the simulated environment, and adds the accessories to rooms in a home. Then your app can control the accessories displayed in HomeKit Accessory Simulator. To test with HomeKit Accessory Simulator, run your app in iOS Simulator, or run it on an iOS device using Xcode. HomeKit Accessory Simulator is an additional developer tool that is not installed with Xcode. To install HomeKit Accessory Simulator, follow the steps in Download HomeKit Accessory Simulator (page 7). Adding Accessories Use HomeKit Accessory Simulator to add some accessories to the simulated network. To add an accessory to the network 1. In HomeKit Accessory Simulator, click the Add button (+) at the bottom of the left column. 2. Choose Add Accessory from the pop-up menu. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 30 Testing Your HomeKit App Adding Services to Accessories 3. Enter an accessory name and manufacturer. 4. Click Finish. To delete an accessory, select the accessory and enter Delete on the keyboard. Adding Services to Accessories An accessory needs a service with characteristics that you can control from your app. You select a service from a predefined list and then customize the characteristics. To add a service to an accessory 1. In HomeKit Accessory Simulator, select the accessory in the Accessories column. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 31 Testing Your HomeKit App Adding Services to Accessories The services for the accessory appear in the detail view. Note: All accessories have an Accessory Information service that appears below all other services in the detail view. You can add characteristics to the Accessory Information service, but you cannot delete the default characteristics. 2. Click Add Service, and choose a type of service from the pop-up menu. The new service appears in the detail view. HomeKit Accessory Simulator creates the common characteristics for that type of service. For example, the default characteristics of a Light Bulb service are Hue, Saturation, Brightness, and On. (The On characteristic is the same as the power state characteristic type, described in 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 32 Testing Your HomeKit App Adding Characteristics to Services Accessing Values of Characteristics (page 27).) Some characteristics are mandatory and others are optional. For example, the On characteristic is mandatory, and the Hue, Saturation, and Brightness characteristics are optional. Adding Characteristics to Services You add characteristics to a service using a predefined list, or you build a custom type. You can add only one characteristic of each kind. To add a characteristic to a service 1. In HomeKit Accessory Simulator, under the service in the detail view, click Add Characteristic. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 33 Testing Your HomeKit App Adding Accessories to a Home in Your App 2. From the Characteristic Type menu, choose a type or Custom. 3. Enter other information about the characteristic in the fields, and click Finish. The new characteristic appears in the detail view. To remove a characteristic, click the minus icon to the right of the characteristic. The icon doesn’t appear if the characteristic is mandatory for a service type. For example, you can remove the Hue, Saturation, and Brightness characteristics of a Light Bulb service, but you cannot remove the On characteristic. Adding Accessories to a Home in Your App After you create an accessory in HomeKit Accessory Simulator, run your app and add the new accessory to a home. To pair an accessory with a home 1. In Xcode, click Run and execute the code that invokes the addAccessory:completionHandler: method (described in Adding Accessories to Homes and Rooms (page 15)). 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 34 Testing Your HomeKit App Controlling Accessories 2. If an Add HomeKit Accessory dialog states that the accessory is not certified (which is allowed in HomeKit Accessory Simulator), click Add Anyway. 3. In the next Add HomeKit Accessory dialog that appears, enter the setup code for the accessory and click Add. In HomeKit Accessory Simulator, the setup code appears below the accessory name in the detail area. To write the code to add an accessory to a home and room, read Creating Homes and Adding Accessories (page 12). Controlling Accessories In HomeKit Accessory Simulator, you can access an accessory’s services and set the values of the service characteristics to simulate controlling the accessory from another HomeKit app, or to simulate manually controlling the accessory. To control an accessory 1. In HomeKit Accessory Simulator, select the accessory in the Accessories column. The services and their characteristics are displayed in the detail view. 2. Manipulate the control for a characteristic to change its value. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 35 Testing Your HomeKit App Adding Bridges For example, to change the Hue, Saturation, and Brightness of a light bulb, move the knob of a corresponding slider. To turn a light bulb off, click No on the On toggle. If your app displays the characteristics of a service, such as a light bulb’s on and off state, it should update the view when you change the characteristic’s value in HomeKit Accessory Simulator. To observe HomeKit database changes, read Observing HomeKit Database Changes (page 19). To write the code to control an accessory from your app, read Accessing Services and Characteristics (page 25). Adding Bridges To simulate accessories that don’t support HomeKit Accessory Protocol, add a bridge and then add the accessories to the bridge. Configuring an accessory behind a bridge is similar to configuring other types of accessories. Adding a Bridge to the Network Add an accessory that represents the bridge. To add a bridge to the network 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 36 Testing Your HomeKit App Adding Bridges 1. In HomeKit Accessory Simulator, click the Add button (+) at the bottom of the Accessories column. 2. Choose Add Bridge from the pop-up menu. 3. Enter an accessory name and manufacturer. 4. Click Finish. Adding Accessories Behind a Bridge Add one or more accessories behind the bridge. To add an accessory to a bridge 1. In the left column in HomeKit Accessory Simulator, select the bridge under Bridges. 2. Choose Add Accessory in the detail view. 3. Enter an accessory name and manufacturer. 4. Click Finish. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 37 Testing Your HomeKit App Adding Bridges to a Home in Your App To view the details of an accessory behind a bridge, select it under the bridge in the Bridges section. If necessary, click the disclosure triangle next to the bridge to reveal its accessories. After you add services and their characteristics to the accessories, as described in Adding Services to Accessories (page 31) and Adding Characteristics to Services (page 33), they appear in the detail area when the bridge is selected. Adding Bridges to a Home in Your App The steps to pair a bridge to a home are the same as the steps to pair an accessory to a home, described in Adding Accessories to a Home in Your App (page 34). The accessories behind the bridge are also added to the home, as described in Adding Bridges to Homes and Rooms (page 16). Controlling Accessories Behind a Bridge The steps to control accessories behind a bridge are the same as the steps to control any accessory, described in Controlling Accessories in HomeKit Accessory Simulator (page 35), except that you select the accessory under the bridge in the left column. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 38 Testing Your HomeKit App Testing Multiple iOS Devices and Users Testing Multiple iOS Devices and Users You can’t test sharing of the HomeKit database between multiple iOS devices and users using iOS Simulator. Instead, install your app on multiple iOS devices, enter the iCloud credentials on those iOS devices, and run your app. Alternatively, use ad hoc provisioning to test your app on multiple registered iOS devices, as described in Distributing Your App Using Ad Hoc Provisioning in App Distribution Guide . ● To test the same user using multiple iOS devices, sign in with the same iCloud account on each iOS device. ● To test multiple users accessing the same home, sign in with different iCloud accounts on each iOS device. Your app should enable a user to add a guest user to the home, as described in Managing Users (page 43). 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 39 Creating Action Sets and Triggers An action set (HMActionSet) and a trigger (HMTimerTrigger) allow you to control many accessories at once. For example, an action set might execute a set of actions (HMAction) just before the user goes to bed. A write action writes a value to a characteristic. The actions in an action set execute in an undefined order. A trigger executes an action set at a given date and can repeat. Action sets have unique names within a home and are recognized by Siri. Creating Write Actions Write actions write the values of characteristics of a service and are added to action sets. The HMAction class is an abstract superclass for the HMCharacteristicWriteAction concrete subclass. An action has an associated characteristic object, so you access a service object and its characteristics, as described in Accessing Services and Characteristics (page 25), to create an associated HMCharacteristicWriteAction object. To create a write action, use the initWithCharacteristic:targetValue: initialization method in the HMCharacteristicWriteAction class. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 40 Creating Action Sets and Triggers Creating and Executing Action Sets HMCharacteristicWriteAction *action = [[HMCharacteristicWriteAction alloc] initWithCharacteristic:characteristic targetValue:value]; In your code, replace the value parameter with the value you want to write, depending on the possible values for the characteristic, and replace characteristic with the HMCharacteristic object that represents the characteristic you want to change. Creating and Executing Action Sets An action set is a collection of actions that are executed together; for example, a nighttime action set might include actions to turn off lights, turn the temperature down, and lock doors. To create an action set, use the addActionSetWithName:completionHandler: asynchronous method. [self.home addActionSetWithName:@"NightTime" completionHandler:^(HMActionSet *actionSet, NSError *error) { if (error == nil) { // Successfully added an action set } else { // Unable to add an action set } }]; To add an action to an action set, use the addAction:completionHandler: asynchronous method. [actionSet addAction:action completionHandler:^(NSError *error) { if (error == nil) { // Successfully added an action to an action set } else { // Unable to add an action to an action set } }]; To remove an action, use the removeAction:completionHandler: method. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 41 Creating Action Sets and Triggers Creating and Enabling Timer Triggers To execute an action set, use the executeActionSet:completionHandler: method in the HMHome class. For example, the user wants to control all holiday lights. You create one action set for turning all holiday lights on and another action set for turning all holiday lights off. To turn the holiday lights on, send the executeActionSet:completionHandler: message to the home object passing the “holiday lights on” action set. Creating and Enabling Timer Triggers Triggers execute one or more action sets. iOS manages and executes triggers for you in the background. The HMTrigger class is an abstract superclass for the HMTimerTrigger concrete subclass. When you create a timer trigger, you specify the fire date and optional recurrence information. Creating and enabling a timer trigger is a multistep process. To create and enable a timer trigger 1. Create a timer trigger. self.trigger = [[HMTimerTrigger alloc] initWithName:name fireDate:fireDate timeZone:nil recurrence:nil recurrenceCalendar:nil]; The fire date must be in the future, and the seconds value must be zero. If you specify a recurrence, the minimum interval is five minutes and the maximum interval is five weeks. To specify a recurrence using the NSDateComponents and NSCalendar parameters, read Date and Time Programming Guide . 2. Add action sets to the trigger. Use the HMTrigger superclass method, addActionSet:completionHandler:, to add an action set to a trigger. 3. Add the trigger to a home. Use the addTrigger:completionHandler: method in the HMHome class to add a trigger to a home. 4. Enable the trigger. Newly created trigger objects are disabled by default. Use the enable:completionHandler: method to enable a trigger. An enabled timer trigger will execute its action sets at the next fire date. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 42 Managing Users The user who creates a home is the admin for the home and can perform all operations including adding guest users to a home. Any user (HMUser) that an admin adds to a home has restricted privileges. Guests can’t modify the home layout in any way but can perform these types of actions: ● Identify accessories ● Read and write characteristic values ● Observe changes to characteristic values ● Execute action sets For example, the head of a household creates a home layout and adds family members to the home. Each family member must have a personal iOS device and Apple ID with an associated iCloud account. The iCloud credentials that family members enter on their iOS devices must match the Apple ID provided by the head of a household in order for them to access the home. For privacy reasons, the Apple ID is hidden from your app. Adding a guest to a home requires the following actions on the admin’s iOS device: 1. The admin user invokes an action to add a guest to a home. 2. Your app invokes the addUserWithCompletionHandler: asynchronous method. 3. HomeKit displays a dialog requesting the guest’s Apple ID. 4. The user enters the guest’s Apple ID in the dialog. 5. The completion handler returns the new user object. 6. Your app displays the guest’s name. Adding a guest to a home requires the following actions on the guest’s iOS device: 1. The user enters the user’s iCloud credentials (the Apple ID and password) in iCloud preferences. 2. The user launches your app. 3. Your app gets the collection of homes from the home manager object. 4. If the iCloud credentials match the Apple ID entered by the admin, the admin’s home appears in the homes property. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 43 Managing Users Adding and Removing Users Some operations performed by a guest may fail. If an asynchronous message to HomeKit fails with error code HMErrorCodeInsufficientPrivileges, the user is not allowed to perform the action—the user is probably a guest, not the admin. To test whether your app handles guest users correctly, read Testing Multiple iOS Devices and Users (page 39). Adding and Removing Users To add a guest user to a home, use the addUserWithCompletionHandler: asynchronous method. [self.home addUserWithCompletionHandler:^(HMUser *user, NSError *error) { if (error == nil) { // Successfully added a user } else { // Unable to add a user } }]; To remove a user from a home, use the removeUser:completionHandler: method in the HMHome class. Implement the home:didAddUser: and home:didRemoveUser: delegate methods in the HMHomeDelegate protocol to update views when other apps add and remove users. To create a home delegate, read Observing Changes to Individual Homes (page 22). Getting User Names For privacy reasons, your app has read-only access to the name of a user, not read or write access to the Apple ID of a user. Use the users property in the HMHome class to get the users of a home. Use the name property of the HMUser class to get the name of a user. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 44 Document Revision History This table describes the changes to HomeKit Developer Guide . Date Notes 2015-02-14 New document that describes common programming and tool tasks using HomeKit. 2015-02-14 | Copyright © 2015 Apple Inc. All Rights Reserved. 45 Apple Inc. Copyright © 2015 Apple Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer or device for personal use only and to print copies of documentation for personal use provided that the documentation contains Apple’s copyright notice. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-branded products. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010 Apple, the Apple logo, Cocoa, Finder, Mac, OS X, Siri, and Xcode are trademarks of Apple Inc., registered in the U.S. and other countries. iCloud is a service mark of Apple Inc., registered in the U.S. and other countries. App Store is a service mark of Apple Inc. IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license. APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED “AS IS,” AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT, ERROR OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. Some jurisdictions do not allow the exclusion of implied warranties or liability, so the above exclusion may not apply to you.
© Copyright 2024