ハイライト
Swift はモバイル、デスクトップ、サーバーをカバー——今年 Apple は組み込みデバイスへ。身近なスマート電球、サーモスタット、センサーの多くは C/C++ ファームウェア。Embedded Swift で Swift の型安全、Optional、クロージャ等でこれらを記述できます。
主要内容
マイコン開発は長年 C/C++ の領域。スマート電球、サーモスタット、センサー——ファームウェアのほぼ全てが C。C はハードウェアレジスタ直接操作可だが型安全が弱く、コールバックは関数ポインタ+無型 context——複雑化でバグ多発。
Apple は今年 Embedded Swift を発表——リソース制約組み込み向けコンパイルモード。値型、参照型、クロージャ、Optional、エラー処理、ジェネリクスを維持し、ランタイムメタデータが必要な機能(リフレクション、any 型、メタ型)を除去。数十 KB RAM のマイコンでも動くサイズ。Apple の Secure Enclave Processor が既に Embedded Swift 使用——安全重要領域でのメモリ安全の価値は明確。
Embedded Swift は実験的、ソース非安定。swift.org からプレビューツールチェーン。ARM/RISC-V(32/64 ビット)対応。bridging header でベンダー C SDK、C++ 相互運用で Matter。
詳細
エントリポイントと C SDK 呼び出し
Embedded Swift のエントリは @_cdecl で C にブリッジ。最小例(03:50):
@_cdecl("app_main")
func app_main() {
print("🏎️ Hello, Embedded Swift!")
}
@_cdecl("app_main")が Swift 関数を C シンボルapp_mainとしてエクスポート。ESP32 SDK が起動時に呼び出し- これがプログラム全体——
@mainなし、SwiftUI なし、ランタイム依存なし
ベンダー SDK の C API を直接呼び出しハードウェア制御(06:48):
@_cdecl("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)
}
led_driver_get_config()/led_driver_init(&config)— bridging header 経由の C SDK 直接呼び出し- C 関数が LED ドライバを操作。Swift 側追加バインディング不要
C API の Swift インターフェース化
C 直接呼び出しは動くが直感的でない。Swift ラッパーが望ましい(08:32):
let led = LED()
@_cdecl("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)
}
}
}
LED()は C SDKled_driver_*を内部呼び出しする Swift ラッパー.red、.hueSaturation(_:_:)は Swift enum 関連値——型安全な色表現Int.random(in:)も組み込みで利用可- マイコン上:LED が 1 秒ごとに点滅、点灯時ランダム色
Matter 経由の HomeKit アクセサリ
Matter はオープンなスマートホーム標準、C++ 実装。Swift は C++ 相互運用で Matter API を直接呼び、発見・ペアリング等の基盤を利用。以下は Home App 制御可能なカラー電球(12:44):
let led = LED()
@_cdecl("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()
}
Matter.Node()がアクセサリ全体。identifyHandlerは C 関数ポインタ+context の代わりにクロージャMatter.ExtendedColorLightは電球エンドポイント。eventHandlerが Home App 全指令を処理event.attributeは Swift enum。switchのパターンマッチで case と関連値(.colorControl(.currentHue)等)をネストなし処理- WiFi で家庭ネットワーク参加後、Home App が自動発見——追加ペアリングロジック不要
Embedded Swift の制限
ランタイムメタデータが必要な機能を除去(18:03):
- ランタイムリフレクション(
Mirror)——型メタデータのコードサイズオーバーヘッド不可 any型——存在型コンテナは型消去にメタデータ必要- メタ型(値としての
MyType.self)——同様にメタデータ依存
代替はジェネリクス(19:24):
// any Countable は Embedded Swift でコンパイルエラー
// some Countable に置換——コンパイラが特化、ランタイムメタデータ不要
func count(countable: some Countable) {
print(countable.count)
}
any Countableをsome Countableに——ジェネリック化・特化でメタデータ不要- Embedded Swift でコンパイル通過するコードはフル Swift でも通過——厳密サブセット、別方言ではない
重要ポイント
-
何をするか:既存 IoT デバイスのファームウェア代替層に Embedded Swift。なぜ価値があるか:C コールバックは関数ポインタ+無型 context。Swift クロージャ・enum・Optional がこの系バグを排除。始め方:swift-embedded-examples から ESP32 テンプレート clone、プレビューツールチェーンで blink、C SDK を Swift ラッパーに段階置換。
-
何をするか:Matter でスマートホームアクセサリ原型。なぜ価値があるか:Matter が発見・ペアリング・HomeKit 互換を提供。Swift ラッパーでビジネスロジック可読。始め方:swift-matter-examples clone、README で ESP32 構築、demo の
eventHandlerパターン参照。 -
何をするか:Swift MMIO ライブラリでレジスタ安全操作。なぜ価値があるか:生レジスタ読書きはオフセットミス・ビットマスク漏れ。Swift MMIO は型安全なレジスタ記述。始め方:swift-mmio 依存追加、
@RegisterBank/@Registerでレイアウト記述。
関連セッション
- Consume noncopyable types in Swift — noncopyable 型は Embedded Swift とゼロコピー理念を共有
- Explore Swift performance — 抽象と性能のバランス、組み込みトレードオフに直結
- Explore the Swift on Server ecosystem — Swift クロスプラットフォームの別方向、サーバーと組み込みで同一言語
- Analyze heap memory — 組み込みメモリ制約、ヒープ分析は Embedded Swift 最適化にも適用
コメント
GitHub Issues · utterances