@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +266 -267
- package/package.json +2 -2
- package/pipeline/scripts/_notices.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +68 -68
- package/pipeline/skills/shared/README.md +70 -70
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -1,392 +1,325 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: homekit-matter
|
|
3
|
-
description: "
|
|
3
|
+
description: "HomeKit and MatterSupport: managing homes, rooms, zones and accessories, reading characteristics, action sets and triggers, Matter commissioning, MatterSupport extensions. Use when controlling smart-home accessories, onboarding Matter devices or building a third-party ecosystem app."
|
|
4
4
|
metadata:
|
|
5
|
-
source:
|
|
5
|
+
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# HomeKit
|
|
8
|
+
# HomeKit and Matter
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- [Setup](#setup)
|
|
17
|
-
- [HomeKit Data Model](#homekit-data-model)
|
|
18
|
-
- [Managing Accessories](#managing-accessories)
|
|
19
|
-
- [Reading and Writing Characteristics](#reading-and-writing-characteristics)
|
|
20
|
-
- [Action Sets and Triggers](#action-sets-and-triggers)
|
|
21
|
-
- [Matter Commissioning](#matter-commissioning)
|
|
22
|
-
- [MatterAddDeviceExtensionRequestHandler](#matteradddeviceextensionrequesthandler)
|
|
23
|
-
- [Common Mistakes](#common-mistakes)
|
|
24
|
-
- [Review Checklist](#review-checklist)
|
|
25
|
-
- [References](#references)
|
|
10
|
+
Two frameworks split the smart-home job. HomeKit is the model of the user's
|
|
11
|
+
house: homes, rooms, accessories, scenes (action sets) and automations
|
|
12
|
+
(triggers). MatterSupport is the onboarding path that brings a Matter device
|
|
13
|
+
into an ecosystem you run yourself. The code here assumes Swift 6.3 and an
|
|
14
|
+
iOS 26 deployment target.
|
|
26
15
|
|
|
27
16
|
## Setup
|
|
28
17
|
|
|
29
|
-
### HomeKit
|
|
18
|
+
### HomeKit
|
|
30
19
|
|
|
31
|
-
1.
|
|
32
|
-
2.
|
|
20
|
+
1. Turn on the **HomeKit** capability in the target's Signing & Capabilities tab.
|
|
21
|
+
2. Put an `NSHomeKitUsageDescription` string in Info.plist that explains
|
|
22
|
+
why the app reads and controls the user's home.
|
|
33
23
|
|
|
34
|
-
|
|
35
|
-
<key>NSHomeKitUsageDescription</key>
|
|
36
|
-
<string>This app controls your smart home accessories.</string>
|
|
37
|
-
```
|
|
24
|
+
### MatterSupport
|
|
38
25
|
|
|
39
|
-
|
|
26
|
+
1. Create a **MatterSupport Extension** target. Its principal class must
|
|
27
|
+
subclass `MatterAddDeviceExtensionRequestHandler`.
|
|
28
|
+
2. Declare three Bonjour types under `NSBonjourServices`: `_matter._tcp`,
|
|
29
|
+
`_matterc._udp`, plus `_matterd._udp`.
|
|
30
|
+
3. The `com.apple.developer.matter.allow-setup-payload` entitlement is needed
|
|
31
|
+
only when the app
|
|
32
|
+
hands a setup payload to the request itself. Apps that let the system
|
|
33
|
+
scan the code do not need it.
|
|
40
34
|
|
|
41
|
-
|
|
35
|
+
### Availability and authorization
|
|
42
36
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
3. Add `com.apple.developer.matter.allow-setup-payload` only if the caller
|
|
48
|
-
supplies a Matter setup payload programmatically
|
|
49
|
-
|
|
50
|
-
### Availability Check
|
|
37
|
+
HomeKit is available on iPhone, iPad, Mac Catalyst, Apple Watch, Apple TV
|
|
38
|
+
and Apple Vision Pro. There is no explicit permission call: creating a home manager and
|
|
39
|
+
setting its delegate starts the load, and the authorization result arrives on
|
|
40
|
+
the delegate.
|
|
51
41
|
|
|
52
42
|
```swift
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let homeManager = HMHomeManager()
|
|
56
|
-
|
|
57
|
-
// HomeKit is available on iPhone, iPad, Apple TV, Apple Watch,
|
|
58
|
-
// Mac Catalyst, and Vision Pro.
|
|
59
|
-
// Authorization is handled through the delegate:
|
|
60
|
-
homeManager.delegate = self
|
|
43
|
+
let manager = HMHomeManager()
|
|
44
|
+
manager.delegate = houseModel // callbacks report homes and authorization
|
|
61
45
|
```
|
|
62
46
|
|
|
63
|
-
## HomeKit
|
|
47
|
+
## The HomeKit object graph
|
|
64
48
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```text
|
|
49
|
+
```
|
|
68
50
|
HMHomeManager
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-> HMZone (groups of rooms)
|
|
75
|
-
-> HMActionSet (grouped actions)
|
|
76
|
-
-> HMTrigger (time or event-based triggers)
|
|
51
|
+
+- HMHome (one or more, one may be primary)
|
|
52
|
+
+- HMRoom -> HMAccessory -> HMService -> HMCharacteristic
|
|
53
|
+
+- HMZone (named group of rooms, e.g. "Upstairs")
|
|
54
|
+
+- HMActionSet (scene)
|
|
55
|
+
+- HMTrigger (timer or event automation)
|
|
77
56
|
```
|
|
78
57
|
|
|
79
|
-
###
|
|
58
|
+
### Loading homes
|
|
80
59
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
60
|
+
Keep exactly one `HMHomeManager` for the process. The database loads in the
|
|
61
|
+
background, so `homes` is empty until the delegate says otherwise.
|
|
62
|
+
`HMHomeManager.primaryHome` still exists but has been deprecated since
|
|
63
|
+
iOS 16.1, so choose the current home in your own UI instead of relying on it.
|
|
84
64
|
|
|
85
65
|
```swift
|
|
86
66
|
import HomeKit
|
|
87
67
|
|
|
88
|
-
final class
|
|
89
|
-
let
|
|
68
|
+
final class HouseModel: NSObject, HMHomeManagerDelegate {
|
|
69
|
+
let manager = HMHomeManager()
|
|
70
|
+
private(set) var houses: [HMHome] = []
|
|
71
|
+
private(set) var mainHouse: HMHome?
|
|
72
|
+
private(set) var canControl = false
|
|
90
73
|
|
|
91
74
|
override init() {
|
|
92
75
|
super.init()
|
|
93
|
-
|
|
76
|
+
manager.delegate = self
|
|
94
77
|
}
|
|
95
78
|
|
|
96
79
|
func homeManagerDidUpdateHomes(_ manager: HMHomeManager) {
|
|
97
|
-
|
|
98
|
-
let
|
|
99
|
-
let primaryHome = manager.primaryHome
|
|
100
|
-
print("Loaded \(homes.count) homes")
|
|
80
|
+
houses = manager.homes
|
|
81
|
+
mainHouse = houses.first // let the user pick when there are several
|
|
101
82
|
}
|
|
102
83
|
|
|
103
|
-
func homeManager(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
) {
|
|
107
|
-
if status.contains(.authorized) {
|
|
108
|
-
print("HomeKit access granted")
|
|
109
|
-
}
|
|
84
|
+
func homeManager(_ manager: HMHomeManager,
|
|
85
|
+
didUpdate status: HMHomeManagerAuthorizationStatus) {
|
|
86
|
+
canControl = status.contains(.authorized)
|
|
110
87
|
}
|
|
111
88
|
}
|
|
112
89
|
```
|
|
113
90
|
|
|
114
|
-
###
|
|
91
|
+
### Rooms
|
|
115
92
|
|
|
116
93
|
```swift
|
|
117
|
-
|
|
94
|
+
let office = house.rooms.first { $0.name == "Office" }
|
|
95
|
+
let unassigned = house.roomForEntireHome() // default room for new accessories
|
|
96
|
+
```
|
|
118
97
|
|
|
119
|
-
|
|
120
|
-
let kitchen = rooms.first { $0.name == "Kitchen" }
|
|
98
|
+
## Accessories
|
|
121
99
|
|
|
122
|
-
|
|
123
|
-
let defaultRoom = home.roomForEntireHome()
|
|
124
|
-
```
|
|
100
|
+
### Which framework owns what
|
|
125
101
|
|
|
126
|
-
|
|
102
|
+
| Task | Owner |
|
|
103
|
+
|---|---|
|
|
104
|
+
| Homes, rooms, services, characteristics, scenes, triggers, automations, HomeKit accessory setup UI, Matter onboarding | HomeKit / MatterSupport |
|
|
105
|
+
| BLE or Wi-Fi discovery descriptors, the accessory picker and its authorization, `ASAccessorySession` events, accessory migration | AccessorySetupKit |
|
|
106
|
+
| Talking to a Bluetooth accessory after it was picked (GATT) | CoreBluetooth |
|
|
107
|
+
| Joining an accessory's temporary Wi-Fi setup network | NetworkExtension |
|
|
127
108
|
|
|
128
|
-
|
|
109
|
+
When a flow starts in AccessorySetupKit, say explicitly where it continues:
|
|
110
|
+
CoreBluetooth for Bluetooth traffic, NetworkExtension for Wi-Fi joins. Neither
|
|
111
|
+
of those is HomeKit automation.
|
|
129
112
|
|
|
130
|
-
|
|
113
|
+
### Adding accessories with the system sheet
|
|
114
|
+
|
|
115
|
+
`HMHome.addAndSetupAccessories(completionHandler:)` presents the system
|
|
116
|
+
discovery sheet, but it has been deprecated since iOS 15.4. On current
|
|
117
|
+
releases drive the same sheet through `HMAccessorySetupManager`:
|
|
131
118
|
|
|
132
119
|
```swift
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
120
|
+
let setup = HMAccessorySetupManager()
|
|
121
|
+
let request = HMAccessorySetupRequest()
|
|
122
|
+
request.homeUniqueIdentifier = house.uniqueIdentifier
|
|
123
|
+
setup.performAccessorySetup(using: request) { result, error in
|
|
124
|
+
if let error { report(error) }
|
|
138
125
|
}
|
|
139
126
|
```
|
|
140
127
|
|
|
141
|
-
###
|
|
128
|
+
### Walking the graph
|
|
142
129
|
|
|
143
130
|
```swift
|
|
144
|
-
for
|
|
145
|
-
print(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
for characteristic in service.characteristics {
|
|
151
|
-
print(" \(characteristic.characteristicType): \(characteristic.value ?? "nil")")
|
|
131
|
+
for device in house.accessories {
|
|
132
|
+
print(device.name, "in", device.room?.name ?? "no room")
|
|
133
|
+
for service in device.services {
|
|
134
|
+
print(" service", service.serviceType)
|
|
135
|
+
for trait in service.characteristics {
|
|
136
|
+
print(" ", trait.characteristicType, String(describing: trait.value))
|
|
152
137
|
}
|
|
153
138
|
}
|
|
154
139
|
}
|
|
155
140
|
```
|
|
156
141
|
|
|
157
|
-
### Moving an
|
|
142
|
+
### Moving an accessory
|
|
158
143
|
|
|
159
144
|
```swift
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
home.assignAccessory(accessory, to: bedroom) { error in
|
|
164
|
-
if let error {
|
|
165
|
-
print("Failed to move accessory: \(error)")
|
|
166
|
-
}
|
|
145
|
+
house.assignAccessory(fan, to: bedroom) { error in
|
|
146
|
+
if let error { report(error) }
|
|
167
147
|
}
|
|
168
148
|
```
|
|
169
149
|
|
|
170
|
-
##
|
|
171
|
-
|
|
172
|
-
### Reading a Value
|
|
150
|
+
## Characteristics
|
|
173
151
|
|
|
174
152
|
```swift
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
characteristic.readValue { error in
|
|
153
|
+
// Read the latest value from the device, then use the cached property.
|
|
154
|
+
powerTrait.readValue { error in
|
|
178
155
|
guard error == nil else { return }
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
156
|
+
let isOn = powerTrait.value as? Bool ?? false
|
|
157
|
+
print("Fan running:", isOn)
|
|
182
158
|
}
|
|
183
|
-
```
|
|
184
159
|
|
|
185
|
-
|
|
160
|
+
// Write a new value.
|
|
161
|
+
powerTrait.writeValue(false) { error in
|
|
162
|
+
if let error { report(error) }
|
|
163
|
+
}
|
|
186
164
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if let error {
|
|
191
|
-
print("Write failed: \(error)")
|
|
192
|
-
}
|
|
165
|
+
// Ask for push updates.
|
|
166
|
+
powerTrait.enableNotification(true) { error in
|
|
167
|
+
if let error { report(error) }
|
|
193
168
|
}
|
|
194
169
|
```
|
|
195
170
|
|
|
196
|
-
|
|
171
|
+
Each of these completion-handler methods also has an `async throws` form,
|
|
172
|
+
for example `try await powerTrait.writeValue(false)`.
|
|
197
173
|
|
|
198
|
-
|
|
174
|
+
Pushed values land in `HMAccessoryDelegate`:
|
|
199
175
|
|
|
200
176
|
```swift
|
|
201
|
-
|
|
202
|
-
|
|
177
|
+
func accessory(_ accessory: HMAccessory,
|
|
178
|
+
service: HMService,
|
|
179
|
+
didUpdateValueFor characteristic: HMCharacteristic) {
|
|
180
|
+
refreshTile(for: characteristic)
|
|
203
181
|
}
|
|
182
|
+
```
|
|
204
183
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
184
|
+
Before writing a number, read `characteristic.metadata` and clamp to its
|
|
185
|
+
range. A brightness write of 500 fails because the device accepts 0 to 100:
|
|
186
|
+
|
|
187
|
+
```swift
|
|
188
|
+
let requested = 500
|
|
189
|
+
let ceiling = dimmer.metadata?.maximumValue?.intValue ?? 100
|
|
190
|
+
let floor = dimmer.metadata?.minimumValue?.intValue ?? 0
|
|
191
|
+
dimmer.writeValue(min(max(requested, floor), ceiling)) { _ in }
|
|
213
192
|
```
|
|
214
193
|
|
|
215
|
-
##
|
|
194
|
+
## Scenes and automations
|
|
216
195
|
|
|
217
|
-
###
|
|
196
|
+
### Building an action set
|
|
218
197
|
|
|
219
|
-
An `HMActionSet`
|
|
198
|
+
An `HMActionSet` bundles several characteristic writes that fire together.
|
|
220
199
|
|
|
221
200
|
```swift
|
|
222
|
-
|
|
223
|
-
guard let
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
characteristic: lightChar,
|
|
229
|
-
targetValue: false as NSCopying
|
|
230
|
-
)
|
|
231
|
-
actionSet.addAction(action) { error in
|
|
232
|
-
guard error == nil else { return }
|
|
233
|
-
print("Action added to Good Night scene")
|
|
201
|
+
house.addActionSet(withName: "Movie Time") { scene, error in
|
|
202
|
+
guard let scene else { return }
|
|
203
|
+
let dim = HMCharacteristicWriteAction(characteristic: lampLevel,
|
|
204
|
+
targetValue: 15 as NSCopying)
|
|
205
|
+
scene.addAction(dim) { error in
|
|
206
|
+
if let error { report(error) }
|
|
234
207
|
}
|
|
235
208
|
}
|
|
236
209
|
```
|
|
237
210
|
|
|
238
|
-
###
|
|
211
|
+
### Running it now
|
|
239
212
|
|
|
240
213
|
```swift
|
|
241
|
-
|
|
242
|
-
if let error {
|
|
243
|
-
print("Execution failed: \(error)")
|
|
244
|
-
}
|
|
214
|
+
house.executeActionSet(movieScene) { error in
|
|
215
|
+
if let error { report(error) }
|
|
245
216
|
}
|
|
246
217
|
```
|
|
247
218
|
|
|
248
|
-
###
|
|
219
|
+
### Timer trigger
|
|
220
|
+
|
|
221
|
+
The fire date is the first occurrence; `recurrence` is an interval between
|
|
222
|
+
firings. For "every day" pass `DateComponents(day: 1)`, never hour and minute.
|
|
249
223
|
|
|
250
224
|
```swift
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
let firstFireDate = Calendar.current.nextDate(
|
|
256
|
-
after: Date(),
|
|
257
|
-
matching: timeOfDay,
|
|
258
|
-
matchingPolicy: .nextTime
|
|
259
|
-
)!
|
|
260
|
-
|
|
261
|
-
let trigger = HMTimerTrigger(
|
|
262
|
-
name: "Nightly",
|
|
263
|
-
fireDate: firstFireDate,
|
|
264
|
-
recurrence: DateComponents(day: 1) // Repeat every day after firstFireDate
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
home.addTrigger(trigger) { error in
|
|
268
|
-
guard error == nil else { return }
|
|
225
|
+
let morning = DateComponents(hour: 6, minute: 45)
|
|
226
|
+
guard let firstRun = Calendar.current.nextDate(after: .now,
|
|
227
|
+
matching: morning,
|
|
228
|
+
matchingPolicy: .nextTime) else { return }
|
|
269
229
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
230
|
+
let wakeUp = HMTimerTrigger(name: "Wake Up",
|
|
231
|
+
fireDate: firstRun,
|
|
232
|
+
recurrence: DateComponents(day: 1))
|
|
273
233
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
234
|
+
house.addTrigger(wakeUp) { error in
|
|
235
|
+
guard error == nil else { return }
|
|
236
|
+
wakeUp.addActionSet(sunriseScene) { error in
|
|
237
|
+
guard error == nil else { return }
|
|
238
|
+
wakeUp.enable(true) { _ in }
|
|
277
239
|
}
|
|
278
240
|
}
|
|
279
241
|
```
|
|
280
242
|
|
|
281
|
-
|
|
243
|
+
The order matters: add the trigger to the home, attach action sets, then enable.
|
|
244
|
+
|
|
245
|
+
### Event trigger
|
|
282
246
|
|
|
283
247
|
```swift
|
|
284
|
-
let
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
predicate: nil
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
home.addTrigger(eventTrigger) { error in
|
|
296
|
-
// Add action sets as above
|
|
248
|
+
let doorOpened = HMCharacteristicEvent(characteristic: contactState,
|
|
249
|
+
triggerValue: 1 as NSCopying)
|
|
250
|
+
let arrival = HMEventTrigger(name: "Hallway On Entry",
|
|
251
|
+
events: [doorOpened],
|
|
252
|
+
predicate: nil)
|
|
253
|
+
house.addTrigger(arrival) { error in
|
|
254
|
+
guard error == nil else { return }
|
|
255
|
+
arrival.addActionSet(hallwayScene) { _ in arrival.enable(true) { _ in } }
|
|
297
256
|
}
|
|
298
257
|
```
|
|
299
258
|
|
|
300
|
-
## Matter
|
|
259
|
+
## Matter onboarding
|
|
301
260
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
### Basic Commissioning
|
|
261
|
+
`MatterAddDeviceRequest` runs the system pairing flow for a Matter device and
|
|
262
|
+
calls into your MatterSupport extension so the device joins your fabric. It
|
|
263
|
+
does not create anything in `HMHome`.
|
|
307
264
|
|
|
308
265
|
```swift
|
|
309
266
|
import MatterSupport
|
|
310
267
|
|
|
311
|
-
func
|
|
312
|
-
guard MatterAddDeviceRequest.isSupported else {
|
|
313
|
-
print("Matter not supported on this device")
|
|
314
|
-
return
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
let topology = MatterAddDeviceRequest.Topology(
|
|
318
|
-
ecosystemName: "My Smart Home",
|
|
319
|
-
homes: [
|
|
320
|
-
MatterAddDeviceRequest.Home(displayName: "Main House")
|
|
321
|
-
]
|
|
322
|
-
)
|
|
268
|
+
func pairNewDevice() async throws {
|
|
269
|
+
guard MatterAddDeviceRequest.isSupported else { return }
|
|
323
270
|
|
|
324
|
-
let
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
showing: .allDevices
|
|
271
|
+
let layout = MatterAddDeviceRequest.Topology(
|
|
272
|
+
ecosystemName: "Brightside",
|
|
273
|
+
homes: [MatterAddDeviceRequest.Home(displayName: "Lake Cabin")]
|
|
328
274
|
)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
275
|
+
let request = MatterAddDeviceRequest(topology: layout,
|
|
276
|
+
setupPayload: nil,
|
|
277
|
+
showing: .allDevices)
|
|
278
|
+
try await request.perform() // presents the pairing sheet
|
|
332
279
|
}
|
|
333
280
|
```
|
|
334
281
|
|
|
335
|
-
|
|
336
|
-
`MTRSetupPayload` as `setupPayload
|
|
337
|
-
setup-payload entitlement.
|
|
282
|
+
If the app already knows the setup code, import `Matter`, build an
|
|
283
|
+
`MTRSetupPayload` and pass it as `setupPayload`. This is the only case that
|
|
284
|
+
needs the setup-payload entitlement.
|
|
338
285
|
|
|
339
|
-
###
|
|
286
|
+
### Narrowing the device list
|
|
340
287
|
|
|
341
288
|
```swift
|
|
342
|
-
|
|
343
|
-
let
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
showing: criteria
|
|
349
|
-
)
|
|
289
|
+
let ours = MatterAddDeviceRequest.DeviceCriteria.vendorID(0xFFF1)
|
|
290
|
+
let oursExceptHub = MatterAddDeviceRequest.DeviceCriteria.all([
|
|
291
|
+
.vendorID(0xFFF1),
|
|
292
|
+
.not(.productID(0x0042))
|
|
293
|
+
])
|
|
294
|
+
let eitherBrand = MatterAddDeviceRequest.DeviceCriteria.any([.vendorID(0xFFF1), .vendorID(0xFFF2)])
|
|
350
295
|
```
|
|
351
296
|
|
|
352
|
-
|
|
353
|
-
`.any(...)` when any one criterion is enough.
|
|
354
|
-
|
|
355
|
-
## MatterAddDeviceExtensionRequestHandler
|
|
297
|
+
## The extension handler
|
|
356
298
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
`super` from those overrides.
|
|
299
|
+
Subclass `MatterAddDeviceExtensionRequestHandler` in the extension and
|
|
300
|
+
override the callbacks you need. Do not call `super` from the overrides.
|
|
360
301
|
|
|
361
302
|
```swift
|
|
362
303
|
import MatterSupport
|
|
363
304
|
|
|
364
|
-
final class
|
|
365
|
-
|
|
305
|
+
final class PairingHandler: MatterAddDeviceExtensionRequestHandler {
|
|
366
306
|
override func validateDeviceCredential(
|
|
367
|
-
_
|
|
368
|
-
MatterAddDeviceExtensionRequestHandler.DeviceCredential
|
|
307
|
+
_ credential: MatterAddDeviceExtensionRequestHandler.DeviceCredential
|
|
369
308
|
) async throws {
|
|
370
|
-
//
|
|
371
|
-
// Throw to reject the device
|
|
309
|
+
// Check attestation; throw to refuse the device.
|
|
372
310
|
}
|
|
373
311
|
|
|
374
312
|
override func rooms(
|
|
375
313
|
in home: MatterAddDeviceRequest.Home?
|
|
376
314
|
) async -> [MatterAddDeviceRequest.Room] {
|
|
377
|
-
|
|
378
|
-
return [
|
|
379
|
-
MatterAddDeviceRequest.Room(displayName: "Living Room"),
|
|
380
|
-
MatterAddDeviceRequest.Room(displayName: "Kitchen")
|
|
381
|
-
]
|
|
315
|
+
[.init(displayName: "Porch"), .init(displayName: "Garage")]
|
|
382
316
|
}
|
|
383
317
|
|
|
384
318
|
override func configureDevice(
|
|
385
319
|
named name: String,
|
|
386
320
|
in room: MatterAddDeviceRequest.Room?
|
|
387
321
|
) async {
|
|
388
|
-
// Save the
|
|
389
|
-
print("Configuring \(name) in \(room?.displayName ?? "no room")")
|
|
322
|
+
// Save the chosen name and room to your service.
|
|
390
323
|
}
|
|
391
324
|
|
|
392
325
|
override func commissionDevice(
|
|
@@ -394,107 +327,59 @@ final class MatterHandler: MatterAddDeviceExtensionRequestHandler {
|
|
|
394
327
|
onboardingPayload: String,
|
|
395
328
|
commissioningID: UUID
|
|
396
329
|
) async throws {
|
|
397
|
-
//
|
|
398
|
-
// into your fabric using the Matter framework
|
|
330
|
+
// Commission into your fabric with the Matter framework.
|
|
399
331
|
}
|
|
400
332
|
}
|
|
401
333
|
```
|
|
402
334
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
### DON'T: Create multiple HMHomeManager instances
|
|
440
|
-
|
|
441
|
-
```swift
|
|
442
|
-
// WRONG -- each instance loads the full database independently
|
|
443
|
-
class ScreenA { let manager = HMHomeManager() }
|
|
444
|
-
class ScreenB { let manager = HMHomeManager() }
|
|
445
|
-
|
|
446
|
-
// CORRECT -- single shared instance
|
|
447
|
-
@Observable
|
|
448
|
-
final class HomeStore {
|
|
449
|
-
static let shared = HomeStore()
|
|
450
|
-
let homeManager = HMHomeManager()
|
|
451
|
-
}
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### DON'T: Write characteristics without checking metadata
|
|
455
|
-
|
|
456
|
-
```swift
|
|
457
|
-
// WRONG -- writing a value outside the valid range
|
|
458
|
-
characteristic.writeValue(500) { _ in }
|
|
459
|
-
|
|
460
|
-
// CORRECT -- check metadata first
|
|
461
|
-
if let metadata = characteristic.metadata,
|
|
462
|
-
let maxValue = metadata.maximumValue?.intValue {
|
|
463
|
-
let safeValue = min(brightness, maxValue)
|
|
464
|
-
characteristic.writeValue(safeValue) { _ in }
|
|
465
|
-
}
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
## Review Checklist
|
|
469
|
-
|
|
470
|
-
- [ ] HomeKit capability enabled in Xcode
|
|
471
|
-
- [ ] `NSHomeKitUsageDescription` present in Info.plist
|
|
472
|
-
- [ ] Single `HMHomeManager` instance shared across the app
|
|
473
|
-
- [ ] `HMHomeManagerDelegate` implemented; homes not accessed before `homeManagerDidUpdateHomes`
|
|
474
|
-
- [ ] `HMHomeDelegate` set on homes to receive accessory and room changes
|
|
475
|
-
- [ ] `HMAccessoryDelegate` set on accessories to receive characteristic updates
|
|
476
|
-
- [ ] Characteristic metadata checked before writing values
|
|
477
|
-
- [ ] Error handling in all completion handlers
|
|
478
|
-
- [ ] MatterSupport extension target and principal handler configured
|
|
479
|
-
- [ ] Matter discovery `NSBonjourServices` entries added
|
|
480
|
-
- [ ] `com.apple.developer.matter.allow-setup-payload` used only when providing setup codes
|
|
481
|
-
- [ ] `MatterAddDeviceRequest.isSupported` checked before performing requests
|
|
482
|
-
- [ ] Matter extension handler implements `commissionDevice(in:onboardingPayload:commissioningID:)`
|
|
483
|
-
- [ ] Action sets tested with the HomeKit Accessory Simulator before shipping
|
|
484
|
-
- [ ] Triggers enabled after creation (`trigger.enable(true)`)
|
|
335
|
+
Network selection, attestation details and a fuller handler are in
|
|
336
|
+
the [commissioning recipes](references/matter-commissioning.md).
|
|
337
|
+
|
|
338
|
+
## Common mistakes
|
|
339
|
+
|
|
340
|
+
- **Reading `homes` straight after init.** It is empty until
|
|
341
|
+
`homeManagerDidUpdateHomes(_:)` fires.
|
|
342
|
+
- **Using the HomeKit setup sheet for an ecosystem app.** Neither
|
|
343
|
+
`addAndSetupAccessories` nor `HMAccessorySetupManager` puts a device in your
|
|
344
|
+
own fabric; that goes through `MatterAddDeviceRequest`.
|
|
345
|
+
- **Missing extension plumbing.** No extension target, no principal handler
|
|
346
|
+
class, or missing Bonjour types all break pairing. The setup-payload
|
|
347
|
+
entitlement is only for apps that pass codes directly.
|
|
348
|
+
- **Several home managers.** Each instance loads the whole home database.
|
|
349
|
+
Share one, for example an `@Observable` store exposed as `static let shared`.
|
|
350
|
+
- **Writing without metadata.** Out-of-range values fail; clamp to
|
|
351
|
+
`minimumValue` and `maximumValue` first.
|
|
352
|
+
|
|
353
|
+
## Review checklist
|
|
354
|
+
|
|
355
|
+
- [ ] HomeKit capability turned on
|
|
356
|
+
- [ ] `NSHomeKitUsageDescription` present
|
|
357
|
+
- [ ] One shared `HMHomeManager`
|
|
358
|
+
- [ ] `HMHomeManagerDelegate` implemented; nothing reads homes before `homeManagerDidUpdateHomes`
|
|
359
|
+
- [ ] `HMHomeDelegate` set on each home to hear about accessory and room changes
|
|
360
|
+
- [ ] Each accessory has an `HMAccessoryDelegate` so pushed values arrive
|
|
361
|
+
- [ ] Characteristic metadata consulted before writes
|
|
362
|
+
- [ ] Every completion handler handles its error
|
|
363
|
+
- [ ] MatterSupport extension target with a principal handler subclass
|
|
364
|
+
- [ ] Matter `NSBonjourServices` entries listed
|
|
365
|
+
- [ ] Setup-payload entitlement only when the app supplies codes
|
|
366
|
+
- [ ] `MatterAddDeviceRequest.isSupported` checked before `perform()`
|
|
367
|
+
- [ ] Extension implements `commissionDevice(in:onboardingPayload:commissioningID:)`
|
|
368
|
+
- [ ] Scenes exercised against HomeKit Accessory Simulator before release
|
|
369
|
+
- [ ] Triggers enabled with `enable(true)` after creation
|
|
485
370
|
|
|
486
371
|
## References
|
|
487
372
|
|
|
488
|
-
-
|
|
489
|
-
-
|
|
490
|
-
-
|
|
491
|
-
-
|
|
492
|
-
-
|
|
493
|
-
-
|
|
494
|
-
-
|
|
495
|
-
-
|
|
496
|
-
-
|
|
497
|
-
-
|
|
498
|
-
-
|
|
499
|
-
-
|
|
500
|
-
|
|
373
|
+
- [Commissioning recipes](references/matter-commissioning.md): SwiftUI store and views, full delegate wiring, service and characteristic tables, advanced extension handler, simulator testing
|
|
374
|
+
- https://developer.apple.com/documentation/homekit
|
|
375
|
+
- https://developer.apple.com/documentation/homekit/hmhomemanager
|
|
376
|
+
- https://developer.apple.com/documentation/homekit/hmhome
|
|
377
|
+
- https://developer.apple.com/documentation/homekit/hmaccessory
|
|
378
|
+
- https://developer.apple.com/documentation/homekit/hmroom
|
|
379
|
+
- https://developer.apple.com/documentation/homekit/hmactionset
|
|
380
|
+
- https://developer.apple.com/documentation/homekit/hmtrigger
|
|
381
|
+
- https://developer.apple.com/documentation/mattersupport
|
|
382
|
+
- https://developer.apple.com/documentation/mattersupport/matteradddevicerequest
|
|
383
|
+
- https://developer.apple.com/documentation/mattersupport/matteradddeviceextensionrequesthandler
|
|
384
|
+
- Apple articles worth reading: "Enabling HomeKit in your app" (under the HomeKit
|
|
385
|
+
documentation) and "Adding Matter support to your ecosystem" (under MatterSupport)
|