$npx -y skills add dpearson2699/swift-ios-skills --skill homekitControl smart-home accessories and commission Matter devices using HomeKit and MatterSupport. Use when managing homes/rooms/accessories, creating action sets or triggers, reading accessory characteristics, onboarding Matter devices, or building a third-party smart-home ecosystem
| 1 | # HomeKit |
| 2 | |
| 3 | Control home automation accessories and commission Matter devices. HomeKit manages |
| 4 | the home/room/accessory model, action sets, and triggers. MatterSupport handles device commissioning into your ecosystem. |
| 5 | |
| 6 | ## Contents |
| 7 | |
| 8 | - [Setup](#setup) |
| 9 | - [HomeKit Data Model](#homekit-data-model) |
| 10 | - [Managing Accessories](#managing-accessories) |
| 11 | - [Reading and Writing Characteristics](#reading-and-writing-characteristics) |
| 12 | - [Action Sets and Triggers](#action-sets-and-triggers) |
| 13 | - [Matter Commissioning](#matter-commissioning) |
| 14 | - [MatterAddDeviceExtensionRequestHandler](#matteradddeviceextensionrequesthandler) |
| 15 | - [Common Mistakes](#common-mistakes) |
| 16 | - [Review Checklist](#review-checklist) |
| 17 | - [References](#references) |
| 18 | |
| 19 | ## Setup |
| 20 | |
| 21 | ### HomeKit Configuration |
| 22 | |
| 23 | 1. Enable the **HomeKit** capability in Xcode (Signing & Capabilities) |
| 24 | 2. Add `NSHomeKitUsageDescription` to Info.plist: |
| 25 | |
| 26 | ```xml |
| 27 | <key>NSHomeKitUsageDescription</key> |
| 28 | <string>This app controls your smart home accessories.</string> |
| 29 | ``` |
| 30 | |
| 31 | ### MatterSupport Configuration |
| 32 | |
| 33 | For Matter commissioning into your own ecosystem: |
| 34 | |
| 35 | 1. Add a **MatterSupport Extension** target and set its principal class to a |
| 36 | `MatterAddDeviceExtensionRequestHandler` subclass |
| 37 | 2. Add `NSBonjourServices` entries for `_matter._tcp`, `_matterc._udp`, and |
| 38 | `_matterd._udp` |
| 39 | 3. Add `com.apple.developer.matter.allow-setup-payload` only if the caller |
| 40 | supplies a Matter setup payload programmatically |
| 41 | |
| 42 | ### Framework Boundary |
| 43 | |
| 44 | | Need | Framework | |
| 45 | |---|---| |
| 46 | | Homes, rooms, accessories, characteristics, actions, triggers | HomeKit | |
| 47 | | Commission Matter into the app ecosystem | MatterSupport | |
| 48 | | Select and authorize a nearby Bluetooth or Wi-Fi accessory | AccessorySetupKit | |
| 49 | | Exchange Bluetooth GATT data after selection | CoreBluetooth | |
| 50 | | Join or configure an accessory's Wi-Fi network after selection | NetworkExtension | |
| 51 | |
| 52 | ## HomeKit Data Model |
| 53 | |
| 54 | HomeKit organizes home automation in a hierarchy: |
| 55 | |
| 56 | ```text |
| 57 | HMHomeManager |
| 58 | -> HMHome (one or more) |
| 59 | -> HMRoom (rooms in the home) |
| 60 | -> HMAccessory (devices in a room) |
| 61 | -> HMService (functions: light, thermostat, etc.) |
| 62 | -> HMCharacteristic (readable/writable values) |
| 63 | -> HMZone (groups of rooms) |
| 64 | -> HMActionSet (grouped actions) |
| 65 | -> HMTrigger (time or event-based triggers) |
| 66 | ``` |
| 67 | |
| 68 | ### Initializing the Home Manager |
| 69 | |
| 70 | Create a single `HMHomeManager` and implement the delegate to know when |
| 71 | data is loaded. HomeKit loads asynchronously -- do not access `homes` until |
| 72 | the delegate fires. |
| 73 | |
| 74 | ```swift |
| 75 | import HomeKit |
| 76 | |
| 77 | final class HomeStore: NSObject, HMHomeManagerDelegate { |
| 78 | let homeManager = HMHomeManager() |
| 79 | |
| 80 | override init() { |
| 81 | super.init() |
| 82 | homeManager.delegate = self |
| 83 | } |
| 84 | |
| 85 | func homeManagerDidUpdateHomes(_ manager: HMHomeManager) { |
| 86 | // Safe to access manager.homes now |
| 87 | let homes = manager.homes |
| 88 | let primaryHome = manager.primaryHome |
| 89 | print("Loaded \(homes.count) homes") |
| 90 | } |
| 91 | |
| 92 | func homeManager( |
| 93 | _ manager: HMHomeManager, |
| 94 | didUpdate status: HMHomeManagerAuthorizationStatus |
| 95 | ) { |
| 96 | if status.contains(.authorized) { |
| 97 | print("HomeKit access granted") |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | ``` |
| 102 | |
| 103 | ### Accessing Rooms |
| 104 | |
| 105 | ```swift |
| 106 | guard let home = homeManager.primaryHome else { return } |
| 107 | |
| 108 | let rooms = home.rooms |
| 109 | let kitchen = rooms.first { $0.name == "Kitchen" } |
| 110 | |
| 111 | // Room for accessories not assigned to a specific room |
| 112 | let defaultRoom = home.roomForEntireHome() |
| 113 | ``` |
| 114 | |
| 115 | ## Managing Accessories |
| 116 | |
| 117 | ### Discovering and Adding Accessories |
| 118 | |
| 119 | Use the [Framework Boundary](#framework-boundary) table before adding an |
| 120 | accessory; only HomeKit/MatterSupport work continues in this skill. |
| 121 | |
| 122 | ```swift |
| 123 | // System UI for accessory discovery |
| 124 | home.addAndSetupAccessories { error in |
| 125 | if let error { |
| 126 | print("Setup failed: \(error)") |
| 127 | } |
| 128 | } |
| 129 | ``` |
| 130 | |
| 131 | ### Listing Accessories and Services |
| 132 | |
| 133 | ```swift |
| 134 | for accessory in home.accessories { |
| 135 | print("\(accessory.name) in \(accessory.room?.name ?? "unassigned")") |
| 136 | |
| 137 | for service in accessory.services { |
| 138 | print(" Service: \(service.serviceType)") |
| 139 | |
| 140 | for characteristic in service.characteristics { |
| 141 | print(" \(characteristic.characteristicType): \(characteristic.value ?? "nil")") |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | ``` |
| 146 | |
| 147 | ### Moving an Accessory to a Room |
| 148 | |
| 149 | ```swift |
| 150 | guard let accessory = home.accessories.first, |
| 151 | let bedroom = home.rooms.first(where: { $0.name == "Bedroom" }) else { return } |
| 152 | |
| 153 | home.assignAccessory(accessory, to: bedroom) { error in |
| 154 | if let error { |
| 155 | print("Failed to move accessory: \(error)") |
| 156 | } |
| 157 | } |
| 158 | ``` |
| 159 | |
| 160 | ## Reading and Writing Characteristics |
| 161 | |
| 162 | ### Reading a Value |
| 163 | |
| 164 | ```swift |
| 165 | let characteristic: HMCharacte |