This demo is an iOS application that integrates Apple's Matter.framework to commission, control, and monitor Matter‑certified devices. It is specifically designed to work with the Silicon Labs SiWG917 development kit. The project follows a clean MVVM architecture with dependency injection, use cases, and repositories, all built with SwiftUI.
This demo is an iOS application that integrates Apple's Matter.framework to commission, control, and monitor Matter‑certified devices. It is specifically designed to work with the Silicon Labs SiWG917 development kit. The project follows a clean MVVM architecture with dependency injection, use cases, and repositories, all built with SwiftUI.
ControlPrototype enables:
- Scanning Matter QR codes to start commissioning.
- Commissioning Matter devices over Bluetooth (PASE) and injecting Wi‑Fi credentials (CASE).
- Displaying a list of commissioned devices (mock data for testing).
- Controlling LED state (on/off) and reading temperature from compatible devices.
- Exploring a dashboard with home status (temperature, humidity, etc.).
The app is intended as a starting point for developers who want to integrate Matter into their iOS apps using Apple's native Matter.framework.
Look at Deployment to know how to launch the project
- Xcode 15.0+ (tested with Xcode 16.4+)
- iOS 15.0+ (Matter requires iOS 15.0 or later)
- Physical device (iPhone/iPad) – Matter does not run on the simulator
- Apple Developer account (to run on device)
- Wi‑Fi network (2.4 GHz recommended for Matter devices)
- Matter‑capable chip (e.g. SiWG917, ESP32‑Matter, etc.)
The project follows MVVM (Model‑View‑ViewModel) with additional layers:
UI (SwiftUI) → ViewModels (ObservableObject) → UseCases → Repository → Matter SDK
SwiftUI Views: DeviceListView, DeviceDetailView, QRScannerView, DashboardView.Manage state and presentation logic (DeviceListViewModel, DeviceDetailViewModel, QRScannerViewModel).
Encapsulate business logic (CommissionDeviceUseCase, ToggleLedUseCase, ReadTemperatureUseCase).
Abstract the Matter SDK (MatterDeviceRepository, MatterDeviceRepositoryImpl).
AppContainer acts as the main assembler and lifecycle manager for the MTRDeviceController.
All Matter interactions are performed asynchronously using async/await and CheckedContinuation to wrap delegate‑based APIs.
ControlPrototype/
├── App/
│ ├── ControlPrototypeApp.swift # SwiftUI App entry point
│ ├── AppContainer.swift # Dependency container & Matter controller
│ └── AppRouter.swift # Legacy routing (replaced by MainTabView)
│
├── Domain/
│ ├── Entities/ # Business models
│ │ ├── MatterDevice.swift
│ │ ├── LedState.swift
│ │ ├── HeaterState.swift
│ │ ├── CoolerState.swift
│ │ └── TemperatureReading.swift
│ │
│ └── UseCases/ # Use cases
│ ├── CommissionDeviceUseCase.swift
│ ├── GetKnownDevicesUseCase.swift
│ ├── ToggleLedUseCase.swift
│ └── ReadTemperatureUseCase.swift
│
├── Data/
│ ├── Protocols/
│ │ └── MatterDeviceRepository.swift # Repository abstraction
│ │
│ └── Repositories/
│ └── MatterDeviceRepositoryImpl.swift # Matter SDK implementation
│
├── Presentation/
│ ├── ViewModels/
│ │ ├── DeviceListViewModel.swift
│ │ ├── DeviceDetailViewModel.swift
│ │ └── QRScannerViewModel.swift
│ │
│ └── Views/
│ ├── DeviceListView.swift
│ ├── DeviceDetailView.swift
│ ├── FeatureCard.swift
│ ├── QRScannerView.swift
│ ├── QRScannerRepresentable.swift # UIKit bridge for VisionKit
│ ├── MainTabView.swift # Main TabView navigation
│ ├── DashboardView.swift # Home dashboard
│ └── HomeDashboardView.swift # Dashboard extension
│
├── Infrastructure/
│ ├── Matter/
│ │ ├── MatterControllerFactory.swift # Matter controller factory
│ │ ├── MatterKeypair.swift # MTRKeypair implementation
│ │ ├── MatterStorage.swift # Persistent storage (UserDefaults)
│ │ ├── CommissioningWorker.swift # Step‑by‑step commissioning helper
│ │ └── MatterError.swift # Custom errors
│ │
│ └── Utils/
│ └── (extensions, helpers)
│
├── Resources/
│ ├── Assets.xcassets/
│ ├── Info.plist # Permissions (Bluetooth, Bonjour, Background modes)
│ └── ...
│
└── Tests/ # (Not yet implemented)
├── UnitTests/
└── UITests/
- Clone the repository
git clone https://github.com/your-username/ControlPrototype.git
cd ControlPrototype- Open the project The project uses no external dependency managers; Apple's Matter.framework is provided by the SDK. Simply open:
open ControlPrototype.xcodeproj- Configure team and bundle identifier
- In Xcode, select your Team under Signing & Capabilities.
- Adjust the Bundle Identifier if needed (must be unique).
- Connect a physical device
- Matter requires Bluetooth and Wi‑Fi capabilities only available on real devices. Connect your iPhone/iPad and select it as the run destination.
- (Optional) Configure Wi‑Fi credentials
- Currently, the SSID and password are hardcoded in MatterDeviceRepositoryImpl.swift inside the commissionDevice method:
let worker = CommissioningWorker(
controller: controller,
nodeID: nodeID,
ssid: "miwifiname", // <-- Change to your network
pass: "12345678" // <-- Change to your password
)Important: Modify these values to match your 2.4 GHz Wi‑Fi network before building.
- Run the app Press Cmd+R and wait for the app to launch on your device.
QR Code Scanning & Commissioning
- Uses DataScannerViewController (VisionKit) to read Matter QR codes.
- Commissioning process managed by CommissioningWorker.
- Automatically sends Wi‑Fi credentials after Bluetooth connection is established.
- Searchable list with pull‑to‑refresh.
- Mock data for testing (6 predefined devices).
- Filtering by name and online/offline status.
- Displays features according to device type (thermostat, light, fan, sensor).
- LED On/Off control via Matter OnOff cluster.
- Temperature reading (Matter Temperature Measurement cluster).
- Main view with a simulated thermostat, statistics cards, and quick actions.
- Fully integrated with MainTabView navigation.
- Home: Dashboard.
- Devices: Device list.
- Settings: Basic settings.
Matter commissioning consists of two main phases: PASE (Bluetooth) and CASE (certificate exchange + Wi‑Fi). Our implementation follows these steps:
- QR Scan: Obtains an MTRSetupPayload.
- Worker creation: CommissioningWorker receives the controller, nodeID, and Wi‑Fi credentials.
- Session start: setupCommissioningSession(with:payload, newNodeID:nodeID) – establishes the Bluetooth link.
- Delegate commissioningSessionEstablishmentDone: Bluetooth connected → send Wi‑Fi credentials via commissionNode(withID:nodeID, commissioningParams:).
- Delegate commissioningComplete: Device successfully commissioned.
It acts as a transient actor that stays alive during the whole process and releases memory when finished, avoiding leaks and state‑related bugs.
let worker = CommissioningWorker(controller: controller, nodeID: nodeID, ssid: wifi, pass: pwd)
try await worker.start(payload: payload)A @MainActor singleton that:
- Holds the single MTRDeviceController instance.
- Initialises MatterDeviceRepositoryImpl.
- Acts as the delegate of the controller to receive commissioning events.
- Factory for creating ViewModels used in navigation.
Matter's delegate protocol requires NSObjectProtocol conformance; as a singleton that updates the UI, it is forced to run on the main thread.
Builds the Matter controller with the minimum required parameters:
- MTRStorage: MatterStorage (UserDefaults with "matter." prefix).
- MTRKeypair: MatterKeypair (EC P‑256 key generation).
- IPK: 16‑byte key (fixed development value).
- Fabric ID: 1.
- Vendor ID: 0xFFF1 (test range).
- Handles storage corruption errors and resets UserDefaults when needed.
Implementation of MTRKeypair using Security.framework (SecKeyCreateRandomKey, SecKeyCreateSignature). Generates ephemeral key pairs (non‑persistent) and signs messages with ECDSA SHA256.
A helper NSObject that implements MTRDeviceControllerDelegate and uses a CheckedContinuation to convert the delegate‑based asynchronous process into an async throws function. It retains itself until the work is complete.
- MatterDeviceRepository: Defines contracts for commissioning, listing, reading attributes, and sending commands.
- MatterDeviceRepositoryImpl: Concrete implementation that uses MTRDevice and its clusters.
- readAttribute: Generic method to read any attribute (temperature, status, etc.).
- toggleLed: Sends on/off commands to the OnOff cluster.
- commissionDevice: Invokes CommissioningWorker.
- Use Cases: Simple wrappers that inject the repository and expose an execute method.
- DeviceListViewModel: Manages the device list (mock) and asynchronous loading.
- DeviceDetailViewModel: Logic for the detail screen; exposes @Published properties for temperature, LED state, etc. Uses the injected use cases.
- QRScannerViewModel: Controls scanning, prevents multiple simultaneous scans, and calls the commissioning use case.
- Error handling: All ViewModels publish an optional errorMessage that is displayed in the UI.
Copyright (c) 2026 Krasamo
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Software that were used
- Simplicity Studio 6 - SiWG917 project base
- Xcode 16.4 - iOS Development
- Visual Studio Code - Code editor
Krasamo - [https://www.krasamo.com/] Andres Trotti - Documentation - andresTrotti
