Skip to main content
ClaudeWave
Skill1.1k repo starsupdated 1mo ago

homekit

The HomeKit skill provides Swift iOS integration for controlling home automation accessories and commissioning Matter smart-home devices. Use it when building apps that manage homes, rooms, accessories, triggers, and action sets; reading or modifying device characteristics; or onboarding Matter devices into a third-party ecosystem. Targets Swift 6.3 and iOS 26 and later.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/dpearson2699/swift-ios-skills /tmp/homekit && cp -r /tmp/homekit/skills/homekit ~/.claude/skills/homekit
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# HomeKit

Control home automation accessories and commission Matter devices. HomeKit manages
the home/room/accessory model, action sets, and triggers. MatterSupport handles device commissioning into your ecosystem.

## Contents

- [Setup](#setup)
- [HomeKit Data Model](#homekit-data-model)
- [Managing Accessories](#managing-accessories)
- [Reading and Writing Characteristics](#reading-and-writing-characteristics)
- [Action Sets and Triggers](#action-sets-and-triggers)
- [Matter Commissioning](#matter-commissioning)
- [MatterAddDeviceExtensionRequestHandler](#matteradddeviceextensionrequesthandler)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)

## Setup

### HomeKit Configuration

1. Enable the **HomeKit** capability in Xcode (Signing & Capabilities)
2. Add `NSHomeKitUsageDescription` to Info.plist:

```xml
<key>NSHomeKitUsageDescription</key>
<string>This app controls your smart home accessories.</string>
```

### MatterSupport Configuration

For Matter commissioning into your own ecosystem:

1. Add a **MatterSupport Extension** target and set its principal class to a
   `MatterAddDeviceExtensionRequestHandler` subclass
2. Add `NSBonjourServices` entries for `_matter._tcp`, `_matterc._udp`, and
   `_matterd._udp`
3. Add `com.apple.developer.matter.allow-setup-payload` only if the caller
   supplies a Matter setup payload programmatically

### Framework Boundary

| Need | Framework |
|---|---|
| Homes, rooms, accessories, characteristics, actions, triggers | HomeKit |
| Commission Matter into the app ecosystem | MatterSupport |
| Select and authorize a nearby Bluetooth or Wi-Fi accessory | AccessorySetupKit |
| Exchange Bluetooth GATT data after selection | CoreBluetooth |
| Join or configure an accessory's Wi-Fi network after selection | NetworkExtension |

## HomeKit Data Model

HomeKit organizes home automation in a hierarchy:

```text
HMHomeManager
  -> HMHome (one or more)
       -> HMRoom (rooms in the home)
            -> HMAccessory (devices in a room)
                 -> HMService (functions: light, thermostat, etc.)
                      -> HMCharacteristic (readable/writable values)
       -> HMZone (groups of rooms)
       -> HMActionSet (grouped actions)
       -> HMTrigger (time or event-based triggers)
```

### Initializing the Home Manager

Create a single `HMHomeManager` and implement the delegate to know when
data is loaded. HomeKit loads asynchronously -- do not access `homes` until
the delegate fires.

```swift
import HomeKit

final class HomeStore: NSObject, HMHomeManagerDelegate {
    let homeManager = HMHomeManager()

    override init() {
        super.init()
        homeManager.delegate = self
    }

    func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
        // Safe to access manager.homes now
        let homes = manager.homes
        let primaryHome = manager.primaryHome
        print("Loaded \(homes.count) homes")
    }

    func homeManager(
        _ manager: HMHomeManager,
        didUpdate status: HMHomeManagerAuthorizationStatus
    ) {
        if status.contains(.authorized) {
            print("HomeKit access granted")
        }
    }
}
```

### Accessing Rooms

```swift
guard let home = homeManager.primaryHome else { return }

let rooms = home.rooms
let kitchen = rooms.first { $0.name == "Kitchen" }

// Room for accessories not assigned to a specific room
let defaultRoom = home.roomForEntireHome()
```

## Managing Accessories

### Discovering and Adding Accessories

Use the [Framework Boundary](#framework-boundary) table before adding an
accessory; only HomeKit/MatterSupport work continues in this skill.

```swift
// System UI for accessory discovery
home.addAndSetupAccessories { error in
    if let error {
        print("Setup failed: \(error)")
    }
}
```

### Listing Accessories and Services

```swift
for accessory in home.accessories {
    print("\(accessory.name) in \(accessory.room?.name ?? "unassigned")")

    for service in accessory.services {
        print("  Service: \(service.serviceType)")

        for characteristic in service.characteristics {
            print("    \(characteristic.characteristicType): \(characteristic.value ?? "nil")")
        }
    }
}
```

### Moving an Accessory to a Room

```swift
guard let accessory = home.accessories.first,
      let bedroom = home.rooms.first(where: { $0.name == "Bedroom" }) else { return }

home.assignAccessory(accessory, to: bedroom) { error in
    if let error {
        print("Failed to move accessory: \(error)")
    }
}
```

## Reading and Writing Characteristics

### Reading a Value

```swift
let characteristic: HMCharacteristic = // obtained from a service

characteristic.readValue { error in
    guard error == nil else { return }
    if let value = characteristic.value as? Bool {
        print("Power state: \(value)")
    }
}
```

### Writing a Value

```swift
// Turn on a light
characteristic.writeValue(true) { error in
    if let error {
        print("Write failed: \(error)")
    }
}
```

### Observing Changes

Enable notifications for real-time updates:

```swift
characteristic.enableNotification(true) { error in
    guard error == nil else { return }
}

// In HMAccessoryDelegate:
func accessory(
    _ accessory: HMAccessory,
    service: HMService,
    didUpdateValueFor characteristic: HMCharacteristic
) {
    print("Updated: \(characteristic.value ?? "nil")")
}
```

## Action Sets and Triggers

### Creating an Action Set

An `HMActionSet` groups characteristic writes that execute together:

```swift
home.addActionSet(withName: "Good Night") { actionSet, error in
    guard let actionSet, error == nil else { return }

    // Turn off living room light
    let lightChar = livingRoomLight.powerCharacteristic
    let action = HMCharacteristicWriteAction(
        characteristic: lightChar,
        targetValue: false as NSCopying
    )
    actionSet.addAction(action) { error in
        guard error == nil else { return
accessorysetupkitSkill

Discover and configure Bluetooth and Wi-Fi accessories using AccessorySetupKit. Use when presenting a privacy-preserving accessory picker, defining discovery descriptors for BLE or Wi-Fi devices, handling accessory session events, migrating from CoreBluetooth permission-based scanning, or setting up accessories without requiring broad Bluetooth permissions.

activitykitSkill

Implement, review, or improve Live Activities and Dynamic Island experiences in iOS apps using ActivityKit. Use when building real-time updating widgets for the Lock Screen and Dynamic Island — delivery tracking, sports scores, ride-sharing status, workout timers, media playback, or any time-sensitive information that updates in real time. Also use when working with ActivityKit, ActivityAttributes, Activity lifecycle (request/update/end), Dynamic Island layouts (compact/minimal/expanded), push-to-update Live Activities, or Lock Screen live widgets.

adattributionkitSkill

Measure ad effectiveness with privacy-preserving attribution using AdAttributionKit. Use when registering ad impressions, handling attribution postbacks, updating conversion values, implementing re-engagement attribution, configuring publisher or advertiser apps, or replacing SKAdNetwork with AdAttributionKit for ad measurement.

alarmkitSkill

Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple Watch system UI. Covers AlarmManager scheduling, AlarmAttributes and AlarmPresentation, system Stop and AlarmButton secondary actions, authorization, state observation, countdown widget-extension handoff, and Live Activity integration. Use when building wake-up alarms, countdown timers, or alarm-style alerts that need Apple's system alarm experience.

app-clipsSkill

Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store Connect experiences, size/capability constraints, NSUserActivity routing, SKOverlay promotion, App Group/keychain handoff, ephemeral notifications, location confirmation, and full-app migration. Use when creating App Clips or wiring App Clip invocation, experience configuration, or full-app handoff.

app-intentsSkill

Implement App Intents for Siri, Shortcuts, Spotlight, widgets, Control Center, and Apple Intelligence on iOS. Covers AppIntent actions, AppEntity and EntityQuery models, AppShortcutsProvider phrases, IndexedEntity Spotlight indexing, WidgetConfigurationIntent, SnippetIntent, and assistant schemas. Use when exposing app actions or entities to system surfaces.

app-store-optimizationSkill

Optimize App Store product pages for search visibility and conversion. Use for App Store Optimization (ASO), keyword research, app name/subtitle/keyword-field strategy, conversion-focused descriptions and promotional text, screenshot captions and ordering, Custom Product Pages with assigned search keywords, In-App Events, Product Page Optimization tests, localized metadata, ratings/review strategy, and in-app review prompt timing with RequestReviewAction or AppStore.requestReview. Also use when routing ASO vs App Store review, privacy/ATT, or StoreKit implementation boundaries.

app-store-reviewSkill

Audits App Store submission readiness and rejection risk across current review guidelines, PrivacyInfo.xcprivacy and required-reason APIs, privacy labels, ATT, StoreKit payments, metadata, entitlements, widgets, and Live Activities. Use when preparing a submission, responding to rejection, reconciling privacy evidence, or separating upload blockers from cleanup.