2024 Swift
Go small with Embedded Swift
Embedded Swift brings the safety and expressivity of Swift to constrained environments. Explore how Embedded Swift runs on a variety of microcontrollers through a demonstration using an off-the-shelf Matter device. Learn how the Embedded Swift subset packs the benefits of Swift into a tiny footprint with no runtime, and discover plenty of resources to start your own Embedded Swift adventure.
Watch at developer.apple.com ↗Chapters
- 0:00 — Introduction
- 0:25 — Agenda
- 0:46 — Why Embedded Swift
- 2:30 — Showcase
- 2:47 — The plan
- 3:39 — Getting started
- 6:19 — Using Swift's interoperability to control the LED
- 7:12 — Using an ergonomic LED struct
- 10:07 — Adding the Matter protocol
- 13:43 — Using a Swift enum in the event handler
- 16:52 — Demo summary
- 17:34 — How Embedded Swift differs
- 19:48 — Explore more
- 21:32 — Wrap up
Code shown on screen · 7 snippets
Empty Embedded Swift application
("app_main")
func app_main() {
print("🏎️ Hello, Embedded Swift!")
} Turning on LED to blue color
("app_main")
func app_main() {
print("🏎️ Hello, Embedded Swift!")
var config = led_driver_get_config()
let handle = led_driver_init(&config)
led_driver_set_hue(handle, 240) // blue
led_driver_set_saturation(handle, 100) // 100%
led_driver_set_brightness(handle, 80) // 80%
led_driver_set_power(handle, true)
} Using an LED object
let led = LED()
("app_main")
func app_main() {
print("🏎️ Hello, Embedded Swift!")
led.color = .red
led.brightness = 80
while true {
sleep(1)
led.enabled = !led.enabled
if led.enabled {
led.color = .hueSaturation(Int.random(in: 0 ..< 360), 100)
}
}
} Matter application controlling an LED light
let led = LED()
("app_main")
func app_main() {
print("🏎️ Hello, Embedded Swift!")
// (1) create a Matter root node
let rootNode = Matter.Node()
rootNode.identifyHandler = {
print("identify")
}
// (2) create a "light" endpoint, configure it
let lightEndpoint = Matter.ExtendedColorLight(node: rootNode)
lightEndpoint.configuration = .default
lightEndpoint.eventHandler = { event in
print("lightEndpoint.eventHandler:")
print(event.attribute)
print(event.value)
switch event.attribute {
case .onOff:
led.enabled = (event.value == 1)
case .levelControl:
led.brightness = Int(Float(event.value) / 255.0 * 100.0)
case .colorControl(.currentHue):
let newHue = Int(Float(event.value) / 255.0 * 360.0)
led.color = .hueSaturation(newHue, led.color.saturation)
case .colorControl(.currentSaturation):
let newSaturation = Int(Float(event.value) / 255.0 * 100.0)
led.color = .hueSaturation(led.color.hue, newSaturation)
case .colorControl(.colorTemperatureMireds):
let kelvins = 1_000_000 / event.value
led.color = .temperature(kelvins)
default:
break
}
}
// (3) add the endpoint to the node
rootNode.addEndpoint(lightEndpoint)
// (4) provide the node to a Matter application, start the application
let app = Matter.Application()
app.eventHandler = { event in
print(event.type)
}
app.rootNode = rootNode
app.start()
} Reflection example
// Reflection needs metadata records
let mirror = Mirror(reflecting: s)
mirror.children.forEach { … }
struct MyStruct {
var count: Int
var name: String
} Unavailable features will produce errors
// Unavailable features will produce errors
protocol Countable {
var count: Int { get }
}
func count(countable: any Countable) {
print(countable.count)
} Prefer generics over “any” types
// Prefer generics over “any” types
protocol Countable {
var count: Int { get }
}
func count(countable: some Countable) {
print(countable.count)
} Resources
Related sessions
-
18 min