mcpField
H
homekit-matter

homekit-matter

github.com/dpearson2699开发1.2k402 次安装13 周前更新
代码仓库

关于 homekit-matter

面向 iOS 开发者的 Swift 技能,讲解通过 HomeKit 管理家庭、房间和配件,并用 MatterSupport 将 Matter 设备配对到自有生态系统。

主要功能

  1. 01管理家庭、房间、配件与服务
  2. 02读取、写入并监听特征值
  3. 03创建动作集和触发器
  4. 04通过 MatterSupport 配对设备
  5. 05检查授权与配置要求

适用场景

  1. 01构建智能家居配件管理功能
  2. 02控制灯具等设备的特征值
  3. 03设置定时或事件触发的家庭动作
  4. 04将 Matter 设备配对到自有生态系统

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dpearson2699/swift-ios-skills --skill homekit-matter

安装后在 Claude Code 中输入/homekit-matter确认已加载。

附带文件references/matter-commissioning.md

详细介绍

HomeKit + MatterSupport

控制家庭自动化配件并配置 Matter 设备。HomeKit 管理家庭/房间/配件模型、操作集和触发器。MatterSupport 负责将设备配置到你的生态系统中。目标平台为 Swift 6.2 / iOS 26+。

目录

设置

HomeKit 配置
  1. 在 Xcode 中启用 HomeKit 功能(Signing & Capabilities)
  2. 在 Info.plist 中添加 NSHomeKitUsageDescription:
<key>NSHomeKitUsageDescription</key>
<string>This app controls your smart home accessories.</string>
MatterSupport 配置

要将 Matter 设备配置到你自己的生态系统中:

  1. 启用 MatterSupport 功能
  2. 在项目中添加 MatterSupport Extension 目标
  3. 如果应用直接提供设置代码,则添加 com.apple.developer.matter.allow-setup-payload 权限
可用性检查
import HomeKit

let homeManager = HMHomeManager()

// HomeKit is available on iPhone, iPad, Apple TV, Apple Watch, Mac, and Vision Pro.
// Authorization is handled through the delegate:
homeManager.delegate = self

HomeKit 数据模型

HomeKit 以层级结构组织家庭自动化:

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)
初始化家庭管理器

创建单个 HMHomeManager,并实现代理以确定数据何时加载完成。HomeKit 会异步加载数据——在代理回调触发前不要访问 homes。

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")
        }
    }
}
访问房间
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()

管理配件

发现并添加配件
// System UI for accessory discovery
home.addAndSetupAccessories { error in
    if let error {
        print("Setup failed: \(error)")
    }
}
列出配件和服务
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")")
        }
    }
}
将配件移至房间
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)")
    }
}

读取和写入特征

读取值
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)")
    }
}
写入值
// Turn on a light
characteristic.writeValue(true) { error in
    if let error {
        print("Write failed: \(error)")
    }
}
观察变化

启用通知以获取实时更新:

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")")
}

操作集和触发器

创建操作集

HMActionSet 会将一组特征写入操作组合起来并一并执行:

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 }
        print("Action added to Good Night scene")
    }
}
执行操作集
home.executeActionSet(actionSet) { error in
    if let error {
        print("Execution failed: \(error)")
    }
}
创建计时器触发器
var dateComponents = DateComponents()
dateComponents.hour = 22
dateComponents.minute = 30

let trigger = HMTimerTrigger(
    name: "Nightly",
    fireDate: Calendar.current.nextDate(
        after: Date(),
        matching: dateComponents,
        matchingPolicy: .nextTime
    )!,
    timeZone: .current,
    recurrence: dateComponents,  // Repeats daily at 22:30
    recurrenceCalendar: .current
)

home.addTrigger(trigger) { error in
    guard error == nil else { return }

    // Attach the action set to the trigger
    trigger.addActionSet(goodNightActionSet) { error in
        guard error == nil else { return }

        trigger.enable(true) { error in
            print("Trigger enabled: \(error == nil)")
        }
    }
}
创建事件触发器
let motionDetected = HMCharacteristicEvent(
    characteristic: motionSensorCharacteristic,
    triggerValue: true as NSCopying
)

let eventTrigger = HMEventTrigger(
    name: "Motion Lights",
    events: [motionDetected],
    predicate: nil
)

home.addTrigger(eventTrigger) { error in
    // Add action sets as above
}

Matter 配置

使用 MatterAddDeviceRequest 将 Matter 设备配置到你的生态系统中。这与 HomeKit 是分开的——它负责处理配对流程。

基本配置
import MatterSupport

func addMatterDevice() async throws {
    guard MatterAddDeviceRequest.isSupported else {
        print("Matter not supported on this device")
        return
    }

    let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "My Smart Home",
        homes: [
            MatterAddDeviceRequest.Home(displayName: "Main House")
        ]
    )

    let request = MatterAddDeviceRequest(
        topology: topology,
        setupPayload: nil,
        showing: .allDevices
    )

    // Presents system UI for device pairing
    try await request.perform()
}
筛选设备
// Only show devices from a specific vendor
let criteria = MatterAddDeviceRequest.DeviceCriteria.vendorID(0x1234)

let request = MatterAddDeviceRequest(
    topology: topology,
    setupPayload: nil,
    showing: criteria
)
组合设备条件
let criteria = MatterAddDeviceRequest.DeviceCriteria.all([
    .vendorID(0x1234),
    .not(.productID(0x0001))  // Exclude a specific product
])

MatterAddDeviceExtensionRequestHandler

要全面支持生态系统,请创建 MatterSupport Extension。该扩展负责处理配置回调:

import MatterSupport

final class MatterHandler: MatterAddDeviceExtensionRequestHandler {

    override func validateDeviceCredential(
        _ deviceCredential: DeviceCredential
    ) async throws {
        // Validate the device attestation certificate
        // Throw to reject the device
    }

    override func rooms(
        in home: MatterAddDeviceRequest.Home?
    ) async -> [MatterAddDeviceRequest.Room] {
        // Return rooms in the selected home
        return [
            MatterAddDeviceRequest.Room(displayName: "Living Room"),
            MatterAddDeviceRequest.Room(displayName: "Kitchen")
        ]
    }

    override func configureDevice(
        named name: String,
        in room: MatterAddDeviceRequest.Room?
    ) async {
        // Save the device configuration to your backend
        print("Configuring \(name) in \(room?.displayName ?? "no room")")
    }

    override func commissionDevice(
        in home: MatterAddDeviceRequest.Home?,
        onboardingPayload: String,
        commissioningID: UUID
    ) async throws {
        // Use the onboarding payload to commission the device
        // into your fabric using the Matter framework
    }
}

常见错误

不要:在代理回调触发前访问 homes
// WRONG -- homes array is empty until delegate is called
let manager = HMHomeManager()
let homes = manager.homes  // Always empty here

// CORRECT -- wait for delegate
func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
    let homes = manager.homes  // Now populated
}
不要:混淆 HomeKit 设置与 Matter 配置
// WRONG -- using HomeKit accessory setup for a Matter ecosystem app
home.addAndSetupAccessories { error in }

// CORRECT -- use MatterAddDeviceRequest for Matter ecosystem commissioning
let request = MatterAddDeviceRequest(
    topology: topology,
    setupPayload: nil,
    showing: .allDevices
)
try await request.perform()
不要:忘记必需的权限
// WRONG -- calling Matter APIs without the MatterSupport entitlement
// Results in runtime error

// CORRECT -- ensure these are set up:
// 1. HomeKit capability for HMHomeManager access
// 2. MatterSupport Extension target for ecosystem commissioning
// 3. com.apple.developer.matter.allow-setup-payload if providing setup codes
不要:创建多个 HMHomeManager 实例
// WRONG -- each instance loads the full database independently
class ScreenA { let manager = HMHomeManager() }
class ScreenB { let manager = HMHomeManager() }

// CORRECT -- single shared instance
@Observable
final class HomeStore {
    static let shared = HomeStore()
    let homeManager = HMHomeManager()
}
不要:未检查元数据就写入特征
// WRONG -- writing a value outside the valid range
characteristic.writeValue(500) { _ in }

// CORRECT -- check metadata first
if let metadata = characteristic.metadata,
   let maxValue = metadata.maximumValue?.intValue {
    let safeValue = min(brightness, maxValue)
    characteristic.writeValue(safeValue) { _ in }
}

审查清单

  • 已在 Xcode 中启用 HomeKit 功能
  • Info.plist 中包含 NSHomeKitUsageDescription
  • 在整个应用中共享单个 HMHomeManager 实例
  • 已实现 HMHomeManagerDelegate;在调用 homeManagerDidUpdateHomes 前不访问 homes
  • 为 homes 设置 HMHomeDelegate,以接收配件和房间变化
  • 为配件设置 HMAccessoryDelegate,以接收特征更新
  • 写入值前已检查特征元数据
  • 所有完成处理程序中都有错误处理
  • 已为 Matter 配置添加 MatterSupport 功能和扩展目标
  • 执行请求前已检查 MatterAddDeviceRequest.isSupported
  • Matter 扩展处理程序实现了 commissionDevice(in:onboardingPayload:commissioningID:)
  • 发布前已使用 HomeKit Accessory Simulator 测试操作集
  • 创建后已启用触发器(trigger.enable(true))

参考资料

评论

支持 Markdown