homekit-matter by dpearson2699/swift-ios-skills
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill homekit-matter控制家庭自动化配件并配网 Matter 设备。HomeKit 管理家庭/房间/配件模型、操作集和触发器。MatterSupport 负责将设备配网到您的生态系统中。目标平台为 Swift 6.2 / iOS 26+。
NSHomeKitUsageDescription:<key>NSHomeKitUsageDescription</key>
<string>此应用控制您的智能家居配件。</string>
要将 Matter 设备配网到您自己的生态系统:
com.apple.developer.matter.allow-setup-payload 权限广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import HomeKit
let homeManager = HMHomeManager()
// HomeKit 在 iPhone、iPad、Apple TV、Apple Watch、Mac 和 Vision Pro 上可用。
// 授权通过委托处理:
homeManager.delegate = self
HomeKit 按层次结构组织家庭自动化:
HMHomeManager
-> HMHome (一个或多个)
-> HMRoom (家庭中的房间)
-> HMAccessory (房间中的设备)
-> HMService (功能:灯、恒温器等)
-> HMCharacteristic (可读/可写的值)
-> HMZone (房间分组)
-> HMActionSet (分组操作)
-> HMTrigger (基于时间或事件的触发器)
创建单个 HMHomeManager 并实现委托以了解数据何时加载。HomeKit 是异步加载的——在委托触发之前不要访问 homes。
import HomeKit
final class HomeStore: NSObject, HMHomeManagerDelegate {
let homeManager = HMHomeManager()
override init() {
super.init()
homeManager.delegate = self
}
func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
// 现在可以安全地访问 manager.homes 了
let homes = manager.homes
let primaryHome = manager.primaryHome
print("已加载 \(homes.count) 个家庭")
}
func homeManager(
_ manager: HMHomeManager,
didUpdate status: HMHomeManagerAuthorizationStatus
) {
if status.contains(.authorized) {
print("HomeKit 访问权限已授予")
}
}
}
guard let home = homeManager.primaryHome else { return }
let rooms = home.rooms
let kitchen = rooms.first { $0.name == "Kitchen" }
// 用于未分配到特定房间的配件的房间
let defaultRoom = home.roomForEntireHome()
// 用于配件发现的系统界面
home.addAndSetupAccessories { error in
if let error {
print("设置失败: \(error)")
}
}
for accessory in home.accessories {
print("\(accessory.name) 在 \(accessory.room?.name ?? "未分配") 中")
for service in accessory.services {
print(" 服务: \(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("移动配件失败: \(error)")
}
}
let characteristic: HMCharacteristic = // 从服务中获取
characteristic.readValue { error in
guard error == nil else { return }
if let value = characteristic.value as? Bool {
print("电源状态: \(value)")
}
}
// 打开灯
characteristic.writeValue(true) { error in
if let error {
print("写入失败: \(error)")
}
}
启用通知以获取实时更新:
characteristic.enableNotification(true) { error in
guard error == nil else { return }
}
// 在 HMAccessoryDelegate 中:
func accessory(
_ accessory: HMAccessory,
service: HMService,
didUpdateValueFor characteristic: HMCharacteristic
) {
print("已更新: \(characteristic.value ?? "nil")")
}
HMActionSet 将一起执行的多个特征值写入操作分组:
home.addActionSet(withName: "晚安") { actionSet, error in
guard let actionSet, error == nil else { return }
// 关闭客厅灯
let lightChar = livingRoomLight.powerCharacteristic
let action = HMCharacteristicWriteAction(
characteristic: lightChar,
targetValue: false as NSCopying
)
actionSet.addAction(action) { error in
guard error == nil else { return }
print("操作已添加到晚安场景")
}
}
home.executeActionSet(actionSet) { error in
if let error {
print("执行失败: \(error)")
}
}
var dateComponents = DateComponents()
dateComponents.hour = 22
dateComponents.minute = 30
let trigger = HMTimerTrigger(
name: "夜间",
fireDate: Calendar.current.nextDate(
after: Date(),
matching: dateComponents,
matchingPolicy: .nextTime
)!,
timeZone: .current,
recurrence: dateComponents, // 每天 22:30 重复
recurrenceCalendar: .current
)
home.addTrigger(trigger) { error in
guard error == nil else { return }
// 将操作集附加到触发器
trigger.addActionSet(goodNightActionSet) { error in
guard error == nil else { return }
trigger.enable(true) { error in
print("触发器已启用: \(error == nil)")
}
}
}
let motionDetected = HMCharacteristicEvent(
characteristic: motionSensorCharacteristic,
triggerValue: true as NSCopying
)
let eventTrigger = HMEventTrigger(
name: "运动感应灯",
events: [motionDetected],
predicate: nil
)
home.addTrigger(eventTrigger) { error in
// 如上所述添加操作集
}
使用 MatterAddDeviceRequest 将 Matter 设备配网到您的生态系统。这与 HomeKit 是分开的——它处理配对流程。
import MatterSupport
func addMatterDevice() async throws {
guard MatterAddDeviceRequest.isSupported else {
print("此设备不支持 Matter")
return
}
let topology = MatterAddDeviceRequest.Topology(
ecosystemName: "我的智能家居",
homes: [
MatterAddDeviceRequest.Home(displayName: "主屋")
]
)
let request = MatterAddDeviceRequest(
topology: topology,
setupPayload: nil,
showing: .allDevices
)
// 显示用于设备配对的系统界面
try await request.perform()
}
// 仅显示来自特定供应商的设备
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)) // 排除特定产品
])
为了获得完整的生态系统支持,请创建一个 MatterSupport 扩展。该扩展处理配网回调:
import MatterSupport
final class MatterHandler: MatterAddDeviceExtensionRequestHandler {
override func validateDeviceCredential(
_ deviceCredential: DeviceCredential
) async throws {
// 验证设备证明证书
// 抛出异常以拒绝设备
}
override func rooms(
in home: MatterAddDeviceRequest.Home?
) async -> [MatterAddDeviceRequest.Room] {
// 返回所选家庭中的房间
return [
MatterAddDeviceRequest.Room(displayName: "客厅"),
MatterAddDeviceRequest.Room(displayName: "厨房")
]
}
override func configureDevice(
named name: String,
in room: MatterAddDeviceRequest.Room?
) async {
// 将设备配置保存到您的后端
print("正在配置 \(name) 到 \(room?.displayName ?? "无房间")")
}
override func commissionDevice(
in home: MatterAddDeviceRequest.Home?,
onboardingPayload: String,
commissioningID: UUID
) async throws {
// 使用配网有效载荷,通过 Matter 框架将设备配网到您的 fabric 中
}
}
// 错误 —— homes 数组在委托被调用前始终为空
let manager = HMHomeManager()
let homes = manager.homes // 此处始终为空
// 正确 —— 等待委托
func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
let homes = manager.homes // 现在已填充
}
// 错误 —— 为 Matter 生态系统应用使用 HomeKit 配件设置
home.addAndSetupAccessories { error in }
// 正确 —— 使用 MatterAddDeviceRequest 进行 Matter 生态系统配网
let request = MatterAddDeviceRequest(
topology: topology,
setupPayload: nil,
showing: .allDevices
)
try await request.perform()
// 错误 —— 在没有 MatterSupport 权限的情况下调用 Matter API
// 会导致运行时错误
// 正确 —— 确保已设置以下内容:
// 1. 用于 HMHomeManager 访问的 HomeKit 能力
// 2. 用于生态系统配网的 MatterSupport Extension 目标
// 3. 如果提供设置码,请添加 com.apple.developer.matter.allow-setup-payload
// 错误 —— 每个实例独立加载完整数据库
class ScreenA { let manager = HMHomeManager() }
class ScreenB { let manager = HMHomeManager() }
// 正确 —— 单个共享实例
@Observable
final class HomeStore {
static let shared = HomeStore()
let homeManager = HMHomeManager()
}
// 错误 —— 写入超出有效范围的值
characteristic.writeValue(500) { _ in }
// 正确 —— 首先检查元数据
if let metadata = characteristic.metadata,
let maxValue = metadata.maximumValue?.intValue {
let safeValue = min(brightness, maxValue)
characteristic.writeValue(safeValue) { _ in }
}
NSHomeKitUsageDescriptionHMHomeManager 实例HMHomeManagerDelegate;在 homeManagerDidUpdateHomes 之前未访问 homesHMHomeDelegate 以接收配件和房间更改HMAccessoryDelegate 以接收特征值更新MatterAddDeviceRequest.isSupportedcommissionDevice(in:onboardingPayload:commissioningID:)trigger.enable(true))references/matter-commissioning.md每周安装量
329
代码仓库
GitHub 星标数
269
首次出现
2026年3月8日
安全审计
安装于
codex326
gemini-cli323
github-copilot323
amp323
cline323
kimi-cli323
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. Targets Swift 6.2 / iOS 26+.
NSHomeKitUsageDescription to Info.plist:<key>NSHomeKitUsageDescription</key>
<string>This app controls your smart home accessories.</string>
For Matter commissioning into your own ecosystem:
com.apple.developer.matter.allow-setup-payload entitlement if your app provides the setup code directlyimport 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 organizes home automation in a hierarchy:
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)
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.
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)")
}
}
Enable notifications for real-time updates:
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")")
}
An HMActionSet groups characteristic writes that execute together:
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
}
Use MatterAddDeviceRequest to commission a Matter device into your ecosystem. This is separate from HomeKit -- it handles the pairing flow.
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
])
For full ecosystem support, create a MatterSupport Extension. The extension handles commissioning callbacks:
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
}
}
// 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
}
// 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
// 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 }
}
NSHomeKitUsageDescription present in Info.plistHMHomeManager instance shared across the appHMHomeManagerDelegate implemented; homes not accessed before homeManagerDidUpdateHomesHMHomeDelegate set on homes to receive accessory and room changesHMAccessoryDelegate set on accessories to receive characteristic updatesMatterAddDeviceRequest.isSupported checked before performing requestscommissionDevice(in:onboardingPayload:commissioningID:)references/matter-commissioning.mdWeekly Installs
329
Repository
GitHub Stars
269
First Seen
Mar 8, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex326
gemini-cli323
github-copilot323
amp323
cline323
kimi-cli323
Notion规范转实现计划工具:AI驱动项目管理,自动生成任务与跟踪进度
495 周安装
React Native 测试模式与工具:TDD、工厂模式、模拟模块实战指南
472 周安装
Tailwind v4 + shadcn/ui 生产级技术栈配置指南:5分钟快速搭建,避免常见错误
511 周安装
批判性思维与逻辑推理指南 - 提升AI智能体分析能力,避免信号稀释与语境坍塌
533 周安装
Three.js 3D Web开发教程 - WebGL/WebGPU图形编程、动画与性能优化指南
484 周安装
用户故事拆分指南:8种模式分解大型故事,提升敏捷开发效率
518 周安装
trigger.enable(true))