-
Notifications
You must be signed in to change notification settings - Fork 3
MatterSupport
Package
SwiftBindings.Apple.MatterSupport· Version26.2.6Auto-published fromapple-frameworks/MatterSupport/MATTERSUPPORT-GUIDE.md.
SwiftBindings.Apple.MatterSupport exposes Apple's
MatterSupport
framework to C# through .NET 10's native Swift interop — direct Swift calls, not
Objective-C proxy wrappers. MatterSupport is the small, high-level entry point
for adding a Matter accessory to the user's home: you describe the ecosystem
topology and hand it a setup payload, and perform() drives Apple's system
commissioning UI. This guide maps that flow to the generated C# surface.
The one structural detail worth knowing up front: MatterAddDeviceRequest.SetupPayload
is typed Matter.MTRSetupPayload — a type from the sibling Matter framework.
MatterSupport therefore takes a NuGet dependency on SwiftBindings.Apple.Matter,
and you import both namespaces. (MTRSetupPayload is an Objective-C type, so its
binding shape follows the Matter guide, not the Swift conventions below.)
- Requirements & install
- Naming conventions
- Quick start: add a device
- Describing the topology
- Device criteria
- The cross-module Matter reference
- Extension request handler
- Memory & threading
- Reference links
- .NET 10.0+
- iOS 16.1+, macOS 13.3+, Mac Catalyst 16.4+
-
MatterAddDeviceRequest.IsSupportedrequires iOS 17+ - macOS host for development
- A Matter entitlement on the consuming app plus the
com.apple.developer.matter.allow-setup-payloadcapability. Theperform()flow only runs on a real device with HomeKit configured.
dotnet add package SwiftBindings.Apple.MatterSupport
using Matter; // MTRSetupPayload comes from here
using MatterSupport; // the request flowMatterSupport binds through the Swift-interop pipeline, so the Swift-to-C# transforms apply:
| Swift | C# | Rule |
|---|---|---|
func perform() async throws |
PerformAsync(CancellationToken = default) |
async methods gain an Async suffix, return Task, and accept a trailing CancellationToken
|
static var isSupported |
MatterAddDeviceRequest.IsSupported |
properties are PascalCase; static is preserved |
obj.ecosystemName |
obj.EcosystemName |
properties are PascalCase |
enum DeviceCriteria { case vendorID(Int) } |
DeviceCriteria class with .Tag + TryGetVendorID(out …) and a static VendorID(nint) factory |
Swift enums-with-payload project to a class: a CaseTag discriminator, TryGet* accessors, and static case factories |
nested MatterAddDeviceRequest.Topology
|
MatterAddDeviceRequest.TopologyType |
a nested type whose name would collide with a member gets a Type suffix |
Note the nested topology type is
TopologyTypein C# (Swift'sMatterAddDeviceRequest.Topology), to avoid clashing with the request'sTopologyproperty.
using Matter;
using MatterSupport;
// 1. Parse the accessory's setup code into a Matter MTRSetupPayload.
using var payload = new MTRSetupPayload("MT:U9VJ0OMV172PX813000");
// 2. Describe where the accessory will live.
using var home = new MatterAddDeviceRequest.Home("Living Room");
using var topology = new MatterAddDeviceRequest.TopologyType("My Ecosystem", new[] { home });
// 3. Build the request and drive Apple's system commissioning UI.
using var request = new MatterAddDeviceRequest(topology, setupPayload: payload);
if (MatterAddDeviceRequest.IsSupported) // iOS 17+
{
await request.PerformAsync();
}PerformAsync() presents Apple's system add-accessory sheet. It only produces a
real result on a device with HomeKit set up and an entitled app — in the
simulator it has nothing to drive. Gate the call on IsSupported.
MatterAddDeviceRequest has three constructors:
// topology + payload (criteria defaults to .allDevices, shouldScanNetworks = true)
new MatterAddDeviceRequest(MatterAddDeviceRequest.TopologyType topology,
Matter.MTRSetupPayload? setupPayload);
// + an explicit device criteria
new MatterAddDeviceRequest(MatterAddDeviceRequest.TopologyType topology,
Matter.MTRSetupPayload? setupPayload,
MatterAddDeviceRequest.DeviceCriteria deviceCriteria);
// + control over network scanning
new MatterAddDeviceRequest(MatterAddDeviceRequest.TopologyType topology,
Matter.MTRSetupPayload? setupPayload,
MatterAddDeviceRequest.DeviceCriteria deviceCriteria,
bool shouldScanNetworks = true);Request properties (read/write): Topology (TopologyType),
SetupPayload (Matter.MTRSetupPayload?), ShowDeviceCriteria
(DeviceCriteria), and ShouldScanNetworks (bool, iOS 16.4+).
The topology describes the ecosystem and the homes the user can choose from. All three nested types are constructed from a display name:
using var home = new MatterAddDeviceRequest.Home("Living Room"); // .DisplayName
using var room = new MatterAddDeviceRequest.Room("Kitchen"); // .DisplayName
using var topology = new MatterAddDeviceRequest.TopologyType(
"My Ecosystem", // .EcosystemName
new[] { home }); // .Homes| Type | Constructor | Members |
|---|---|---|
MatterAddDeviceRequest.Home |
new Home(string displayName) |
DisplayName |
MatterAddDeviceRequest.Room |
new Room(string displayName) |
DisplayName |
MatterAddDeviceRequest.TopologyType |
new TopologyType(string ecosystemName, IEnumerable<Home> homes) |
EcosystemName, Homes
|
Each of these also exposes EncodeToJson() / static DecodeFromJson(byte[])
for serializing the request shape.
MatterAddDeviceRequest.DeviceCriteria is a projected Swift enum-with-payload —
it filters which accessories the picker will offer. Build it from the static
case factories, and discriminate an existing value via .Tag / TryGet*:
// Pre-built singleton: no filtering (the default for the 2-arg ctor)
using var any = MatterAddDeviceRequest.DeviceCriteria.AllDevices;
// Case factories (each returns a DeviceCriteria)
var byVendor = MatterAddDeviceRequest.DeviceCriteria.VendorID(0x1234);
var byProduct = MatterAddDeviceRequest.DeviceCriteria.ProductID(0x5678);
var bySerial = MatterAddDeviceRequest.DeviceCriteria.SerialNumber("ABC123");
var byUuid = MatterAddDeviceRequest.DeviceCriteria.CommissioningID(someGuid);
var anyOf = MatterAddDeviceRequest.DeviceCriteria.Any(new[] { byVendor, byProduct });
var allOf = MatterAddDeviceRequest.DeviceCriteria.All(new[] { byVendor, bySerial });
var negated = MatterAddDeviceRequest.DeviceCriteria.Not(byVendor);
var fabric = MatterAddDeviceRequest.DeviceCriteria.FabricNode(rootPublicKey, nodeID);DeviceCriteria.CaseTag values: Any, All, Not, CommissioningID,
VendorID, ProductID, SerialNumber, FabricNode, AllDevices. Inspect a
value with the matching accessor:
using var criteria = request.ShowDeviceCriteria;
if (criteria.Tag == MatterAddDeviceRequest.DeviceCriteria.CaseTag.VendorID &&
criteria.TryGetVendorID(out nint vendor))
{
// …
}SetupPayload is the binding's one cross-framework type: it's
Matter.MTRSetupPayload, an Objective-C class from the sibling Matter package,
flowing through a Swift API.
using var payload = new MTRSetupPayload("MT:U9VJ0OMV172PX813000"); // Matter (ObjC)
using var request = new MatterAddDeviceRequest(topology, setupPayload: payload);
Matter.MTRSetupPayload? roundTrip = request.SetupPayload; // getter unwraps the Swift optional
uint? passcode = roundTrip?.SetupPasscode?.UInt32Value;The getter returns Matter.MTRSetupPayload? (nullable). Because it crosses
module boundaries, restoring SwiftBindings.Apple.MatterSupport automatically
pulls in SwiftBindings.Apple.Matter; you only need to add the one package. See
the Matter guide for everything MTRSetupPayload can do.
For an out-of-app Matter setup extension (where your app participates in
commissioning network selection), subclass
MatterAddDeviceExtensionRequestHandler (an NSObject subclass) and override
its async hooks:
| Override | Purpose |
|---|---|
SelectWiFiNetworkAsync(IEnumerable<WiFiScanResult>, …) |
choose a Wi-Fi network for the accessory; returns a WiFiNetworkAssociation
|
SelectThreadNetworkAsync(IEnumerable<ThreadScanResult>, …) |
choose a Thread network; returns a ThreadNetworkAssociation
|
CommissionDeviceAsync(Home?, string onboardingPayload, Guid commissioningID, …) |
perform the actual commissioning |
RoomsAsync(Home?, …) |
report the rooms available in a home |
ConfigureDeviceAsync(string name, Room?, …) |
name / place the device |
ValidateDeviceCredentialAsync(DeviceCredential, …) |
validate the accessory's credential |
Helper factories for the network-association return types:
var wifi = MatterAddDeviceExtensionRequestHandler.WiFiNetworkAssociation.Network(ssid, credentials);
var thread = MatterAddDeviceExtensionRequestHandler.ThreadNetworkAssociation.Network(extendedPANID);
// Or defer to the system-configured network:
var dflt = MatterAddDeviceExtensionRequestHandler.WiFiNetworkAssociation.DefaultSystemNetwork;Generated types implement ISwiftObject / IDisposable. For short-lived locals
the finalizer cleans up, but using var is the recommended pattern for
deterministic cleanup — Dispose is safe on every generated type and
double-Dispose is a no-op.
using var home = new MatterAddDeviceRequest.Home("Living Room");
using var topology = new MatterAddDeviceRequest.TopologyType("My Ecosystem", new[] { home });
using var request = new MatterAddDeviceRequest(topology, setupPayload: payload);-
PerformAsync()drives system UI. It's@MainActor-bound in Swift; the binding handles the hop — you justawaitit. Continuations resume on a thread-pool thread, so marshal back to your UI thread before touching UI. It only does anything real on a HomeKit-configured device with an entitled app. -
SetupPayloadis nullable. The getter returnsMatter.MTRSetupPayload?— null-check before dereferencing. -
Extension overrides run in a separate process. The
MatterAddDeviceExtensionRequestHandlerhooks execute in Apple's setup extension, not your main app.
- Apple — MatterSupport framework
- Apple — MatterAddDeviceRequest
-
Matter guide — the
MTRSetupPayloadtypeSetupPayloadexposes
-
ActivityKit —
SwiftBindings.Apple.ActivityKitv26.2.6 -
CryptoKit —
SwiftBindings.Apple.CryptoKitv26.2.6 -
FamilyControls —
SwiftBindings.Apple.FamilyControlsv26.2.6 -
LiveCommunicationKit —
SwiftBindings.Apple.LiveCommunicationKitv26.2.6 -
Matter —
SwiftBindings.Apple.Matterv26.2.6 -
MatterSupport —
SwiftBindings.Apple.MatterSupportv26.2.6 -
MusicKit —
SwiftBindings.Apple.MusicKitv26.2.6 -
ProximityReader —
SwiftBindings.Apple.ProximityReaderv26.2.6 -
RealityFoundation —
SwiftBindings.Apple.RealityFoundationv26.2.6 -
RealityKit —
SwiftBindings.Apple.RealityKitv26.2.6 -
RoomPlan —
SwiftBindings.Apple.RoomPlanv26.2.6 -
StoreKit2 —
SwiftBindings.Apple.StoreKit2v26.2.6 -
TipKit —
SwiftBindings.Apple.TipKitv26.2.6 -
Translation —
SwiftBindings.Apple.Translationv26.2.6 -
WeatherKit —
SwiftBindings.Apple.WeatherKitv26.2.6 -
WorkoutKit —
SwiftBindings.Apple.WorkoutKitv26.2.6