스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Embedded Swift로 경량화하기
Embedded Swift를 사용하면 제한된 환경에도 Swift의 안전성과 표현성을 그대로 누릴 수 있습니다. 규격화된 Matter 기기를 사용한 데모를 통해 Embedded Swift에서 다양한 마이크로컨트롤러를 실행하는 방법을 확인해 보세요. Embedded Swift 하위 집합이 그토록 작은 공간에 런타임 없이 Swift의 이점을 모두 담을 수 있었던 방법과 Embedded Swift 개발의 첫걸음을 돕는 수많은 리소스를 살펴볼 수 있습니다.
챕터
- 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
리소스
- A Vision for Embedded Swift
- Embedded Swift User Manual
- Forum: Programming Languages
- Swift Embedded Example Projects
- Swift Forums Embedded Discussion
- Swift Matter Examples
- Swift MMIO
- Tools used: Neovim
관련 비디오
WWDC21
-
다운로드
안녕하세요 저는 Kuba Mracek입니다 아시듯이 Swift는 Apple 플랫폼과 그 외의 플랫폼 모두를 위한 애플리케이션을 빌드하는 데 사용할 수 있는 강력한 언어입니다 오늘은 새롭고 흥미롭지만 더 작은 곳인 임베디드 기기로 이를 가져갑니다 먼저 Embedded Swift를 소개하고 이를 사용해 실질적인 콘텐츠를 빌드하는 방법의 데모를 보여 드리겠습니다 Embedded Swift가 데스크탑 및 모바일 애플리케이션 작성에 사용하는 Swift와 어떻게 다른지 살펴보겠습니다 마지막으로, 더 자세히 알아볼 수 있는 리소스를 공유하겠습니다 시작해 보죠! 현재, Swift로 다양한 유형의 소프트웨어를 빌드할 수 있습니다 모바일 기기, 데스크탑 컴퓨터 서버를 대상으로 지정할 수 있죠
이 세션에서는 새로운 영역에서의 Swift 사용에 대해 살펴보겠습니다 바로 임베디드 기기입니다 일상 생활에서 우리를 둘러싼 스마트 조명, 온도 조절기, 알람 스마트 팬, 음악 기기 조명 스트립, 기타 많은 일반 장치는 프로그래밍 가능한 마이크로컨트롤러를 사용해 빌드됩니다 오늘은 여러분이 취미로 또는 보다 진지한 개발자로서 Swift를 사용해 임베디드 기기를 프로그래밍하는 방법을 설명합니다 이를 위해 Embedded Swift를 소개합니다 제한된 임베디드 기기에 특히 적합한 새로운 컴파일 모드입니다 이전에는 C 및 C++가 이 영역에서 일반적으로 사용된 언어였지만 지금은 이러한 곳에서 Swift 사용을 지원하고 있으며 이에 따라 임베디드 개발자가 Swift 이점을 누리게 되었죠 인체공학 기능, 안전 기능 사용 편의성 등입니다
Embedded Swift는 물론 임베디드 기기의 마이크로컨트롤러뿐만 아니라 새로운 종속성 발생에 민감할 수 있는 커널 수준 코드와 기타 하위 수준 라이브러리 코드를 프로그래밍하는 데 적합합니다 Apple 기기는 Secure Enclave Processor에서 Embedded Swift를 사용하며, Swift의 메모리 안전은 플랫폼에 막대한 이점입니다 Embedded Swift는 Swift의 하위 집합으로 여러분이 알고 좋아하는 대부분의 언어를 다루며 값 및 참조 유형 클로저, 선택 사항, 오류 처리 제네릭 등에 대한 지원을 포함하는 전체 기능을 갖춘 하위 집합입니다 이제 Embedded Swift를 라이브 데모로 살펴보겠습니다
시작하기 전에 Embedded Swift는 현재 실험적 기능이며, 아직 소스가 안정적이지 않다는 점에 유의해야 합니다 현재 개발을 진행 중이며 이를 사용하는 가장 좋은 방법은 swift.org에서 미리보기 툴체인을 사용하는 것입니다
이 데모에서는 매우 간단한 HomeKit 액세서리의 프로토타입을 빌드하겠습니다 바로, 색상 LED 조명입니다 작동하는 HomeKit 설정, 즉 Wi-Fi 네트워크를 설정하고 기존 Apple 기기를 모두 여기에 연결하는 것으로 시작해 보죠 프로그래밍 가능한 임베디드 기기 구체적으로 ESP32C6 개발 보드를 사용할 텐데요, 여기에는 RISC-V 마이크로컨트롤러가 탑재되어 있습니다 또한 색상 LED가 부착되어 있습니다 Mac을 사용해 USB 케이블로 기기에 연결하고 Embedded Swift로 HomeKit 액세서리를 구현하는 프로그램을 작성한 다음 기기로 플래싱합니다 그러면 기기가 Wi-Fi와 HomeKit 네트워크에 연결되고 Apple 기기의 홈 앱에서 해당 기기를 제어할 수 있습니다
그럼 시작하겠습니다 Neovim과 CMake를 사용하는데 현재로서는 기본 사항을 보여 주고 Embedded Swift 코드를 실행하는 템플릿 프로젝트일 뿐입니다 이 프로젝트는 기기 공급업체에서 받은 타사 SDK를 사용합니다 C로 작성된 SDK입니다 해당 SDK를 수정하고 싶지 않기 때문에 브리징 헤더를 사용해 모든 SDK의 API를 Swift에 가져올 수 있습니다
해당 공급업체의 SDK와 해당 빌드 시스템을 기반으로 Swift 코드를 빌드하려면 간단한 CMake 로직이 필요하며 여기에는 상용구 파일도
몇 개 더 필요합니다 예를 들면 YAML 파일
CSV 파일
’sdkconfig’ 파일 등입니다
이들은 이 SDK를 기반으로 빌드되는 모든 프로젝트에 필요하며, 저는 공급업체의 기존 예제를 토대로 이를 설정하고 그 위에 Swift를 추가했습니다
제가 작성한 Swift 소스 코드로 돌아가 보겠습니다 편집기에 LSP가 통합되어 있어 제가 사용하는 함수와 유형에 대한 정의와 문서를 보여 줍니다
풍부하고 의미론적인 자동 완성 기능을 제공할 수 있습니다
제가 말이 안 되는 코드를 작성하면
즉시 오류가 발생하고 경고를 통해 무엇이 잘못인지 알려 줍니다 이제 기기를 연결해 보겠습니다
USB를 통해 이 기기를 프로그래밍하려고 하지만 브레드보드에도 별도의 배터리가 있기 때문에 프로그래밍한 후 기기를 분리해도 계속 사용할 수 있습니다 하지만 먼저, 가장 기본적인 Swift 애플리케이션을 기기에서 작동 및 실행시켜 보죠 제가 사용하는 SDK에서는 이를 위한 도구를 제공합니다
공급업체에서 제공하는 이 편리한 Python 스크립트를 실행해 보죠 기기의 빌드, 플래싱, 모니터링을 모두 한 명령으로 수행할 수 있죠
실행하면서, 펌웨어가 빌드되고 기기에 업로드되는 것을 관찰할 수 있고, 그런 다음 기기로부터 로그를 다시 받습니다 그러면 임베디드 기기에서 실행되는 우리의 첫 번째 Embedded Swift 애플리케이션이 작동 중임을 알 수 있습니다 이제 더 유용한 작업을 하는 코드를 추가해 보겠습니다 Swift 상호운용성 덕분에 공급업체 SDK에서 모든 API가 사용 가능하죠 기기의 LED를 제어하고 싶다면 SDK에서 해당 용도를 위한 기존 C API를 사용할 수 있습니다
이러한 API를 ’파란색’ ’100% 채도’ ’80%’ 밝기를 의미하는 값으로 호출해 보죠
이 버전의 코드를 저장하고 기기에 업로드해 보겠습니다
지난번과 동일한 명령을 실행하겠습니다
몇 초 후, 펌웨어가 업로드되고 기기가 재부팅되면 이제 LED의 색상과 밝기를 제어할 수 있습니다
모든 것에 Swift를 사용해 C API를 호출하면 전체 목적이 무산됩니다 그렇게 할 수 있다는 것은 매우 유용하지만 그 위에 래퍼와 추상화를 빌드한다면 훨씬 더 좋을 겁니다 깔끔하고 직관적이며 인체공학적인 Swift 코드로 작성할 수 있도록요 이 버전에서는 LED 객체를 준비했으니, 바로 정의를 살펴보죠
이것은 제가 작성한 헬퍼 코드인데 C API를 멋진 Swift 레이어로 래핑합니다 인체공학적인 유형을 사용해 유용한 속성을 제공합니다 예를 들어, 활성화된 속성은 불리언이고 밝기 속성은 정수입니다 주요 애플리케이션 로직을 사용해 다시 파일로 돌아가 보겠습니다 LED 객체를 사용해 간결하고 직관적인 코드를 작성할 수 있죠
먼저, 색상을 빨간색으로 설정해 보겠습니다
또한 밝기를 80%로 설정합니다
이와 같은 코드는 매우 가독성이 높고 명확합니다
조금 더 추가해 보죠
루프에서 1초를 기다렸다가 LED의 상태를 바꾸겠습니다 LED를 켜는 경우 새로운 색상을 요청하며 이는 색조 및 채도 값으로 표현됩니다 색조는 무작위이고 채도는 100%가 됩니다 이 모든 Embedded Swift 코드는 일반 Swift 작성과 같습니다 해당 언어의 대부분을 사용할 수 있습니다 펌웨어를 한 번 더 업로드하겠습니다
결과가 정상 작동하는지 보죠 프로그램이 부팅되고 실행되면 기기의 LED가 색상이 무작위로 변경되면서 깜박일 것입니다
훌륭하네요! 정확히 우리가 원했던 대로입니다 LED 객체의 레이어를 빌드하면 깔끔하고 가독성 높은 코드를 작성하게 해 주는 상위 수준 API인 Swift를 활용할 수 있습니다
지금까지 Embedded Swift가 어떻게 워크플로에 통합되는지 살펴봤죠 이를 공급업체가 제공하는 SDK와 함께 사용할 수 있으며 IDE나 텍스트 편집기에서 완전 자동 완성 기능을 제공하고 정의와 문서를 표시하도록 할 수 있습니다 Swift 상호운용성을 활용하여 Swift 코드에서 직접 SDK로부터 기존 C API를 호출할 수 있습니다 하지만 C API를 코어 애플리케이션 로직에 대한 인체공학적이고 직관적인 API를 제공하는 레이어로 래핑하는 것이 종종 중요합니다
이제 기본 사항을 익혔으니 계속해서 실제 HomeKit 액세서리를 빌드해 보겠습니다 이를 위해 ’Matter’ 프로토콜을 사용합니다 Matter는 스마트 홈 액세서리를 빌드하는 개방형 표준입니다 2021년의 WWDC 세션에서 자세히 설명한 바 있으니 자세히 알아보시려면 해당 세션을 시청하시기 바랍니다
제가 사용하고 있는 SDK에서는 Matter가 C++ API로 제공되며 Swift의 상호운용성을 다시 활용하여 기기 탐색 및 작동 같은 모든 인프라 요소를 제공하는 이 기능을 무료로 사용할 수 있죠
Matter 프로토콜을 구현하는 기기가 만들어지는 즉시 HomeKit에서 자동으로 작동합니다 Matter 액세서리를 기본적으로 지원하기 때문입니다 아무 작업도 하지 않는 빈 애플리케이션으로 다시 시작하죠 Matter로 작업하려면 Matter의 데이터 모델과 용어에 대해 조금 알아야 합니다 이것은 Matter 기기를 구현하기 위해 우리가 해야 할 대략적인 상위 수준 작업 목록입니다 루트 노드라는 항목을 생성해야 하는데 이는 전체 Matter 액세서리를 나타냅니다 그런 다음 엔드포인트가 필요한데 이 경우에는 색상 LED 조명입니다 이는 색상과 밝기 등의 상태를 갖는 객체가 될 것이며 조명 켜기 또는 끄기와 같은 명령을 수신할 수 있습니다
그런 다음 엔드포인트를 노드에 연결하고 해당 노드를 ’application’ 객체에 연결합니다 제가 이미 C++ Matter API에 대한 간단한 래퍼 레이어를 작성했는데 이 ’Matter’ 하위 디렉토리에 있습니다
LED 조명과 관련한 작업을 할 때 멋진 API를 제공하기 위해 사용했던 것과 정확히 동일한 접근 방식입니다 이를 사용하면 최상위 로직을 쉽게 채울 수 있습니다
먼저, 루트 노드를 생성합니다
그런 다음 엔드포인트를 생성하고 구성합니다
이것은 색상 조명으로, 특히 eventHandler, 즉 HomeKit의 이벤트가 이 엔드포인트에 전달될 때마다 트리거되는 클로저가 있죠 클로저는 콜백을 위한 매우 자연스러운 메커니즘입니다 안전하지 않은 함수 포인터나 C의 콜백에 대한 일반적인 솔루션인 유형이 지정되지 않은 맥락 인수를 처리할 필요는 없습니다 다음으로, 엔드포인트를 등록해 보겠습니다 그리고 마지막으로, Matter 애플리케이션을 설정하고 시작하죠
지금은 로직이 모든 이벤트를 표시하지만 이제 유효한 Matter 애플리케이션을 빌드했습니다 이 애플리케이션을 기기에 플래싱해 보겠습니다
시작하는 데 시간이 좀 걸립니다 이제 일반적으로, 새 액세서리의 설정 프로세스를 거칩니다 이전에 이미 이 작업을 완료했고 이 기기를 HomeKit 네트워크에 이미 등록했으므로 연결할 Wi-Fi 네트워크를 이미 알고 있습니다 이 작업을 수행하는 즉시 기기가 제 Mac 및 다른 기기의 홈 앱에 ’Matter 액세서리’로 나타납니다
스마트 조명으로 표시되고 제 Mac의 홈 앱에서 곧바로 제어할 수 있습니다 조명을 켜고 끌 수 있으며 이렇게 할 때 기기 로그에 표시되는 명령에 대한 이벤트가 발생합니다
지금까지는 단지 수신 이벤트를 기록했습니다 이제 실제로 뭔가를 수행하도록 해 보죠! 이전에 사용했던 LED 객체에 연결해 보겠습니다 이벤트 핸들러 내부에서, 설정되는 다양한 속성에 반응하고자 합니다 또한 속성이 Swift 열거형이므로 switch 구문을 사용할 수 있으며
자동 완성 기능이 우리가 어떤 경우를 처리해야 하는지 알려 주죠
다양한 속성에 대한 코드를 입력해 보겠습니다 어떤 이벤트를 수신하는지에 따라 조명을 켜거나 꺼야 하는 경우 활성화된 속성을 설정하고자 합니다 또는 밝기 속성을 설정할 때에는 값도 적절히 조절해야 합니다 또한 매우 비슷하게 색상 변경을 처리할 때에는 새로운 색조, 채도, 색온도를 설정할 수 있습니다 이것이 우리에게 필요한 전부입니다 이 프로그램을 기기에 플래싱하고 테스트해 보죠!
프로그램이 시작되는 동안 Swift 열거형이 얼마나 유용하고 인체공학적인지 강조하고 싶습니다
가장 간단한 경우, 열거형은 세트 중 하나의 선택을 나타내죠 예를 들면, 속성의 .onOff 또는 .levelControl의 경우입니다
하지만 연관된 값을 가질 수도 있습니다 예를 들어 .colorControl의 경우에는 페이로드가 있으며 Swift의 패턴 매칭 덕분에 두 번째 중첩된 switch 구문이 필요하지 않습니다 열거형 경우를 페이로드와 매칭시킬 수 있습니다
또한 열거형을 사용하여 색상 속성을 나타내며
이는 색조 및 채도이거나 온도일 수 있습니다
이러한 경우에도 다양한 페이로드 유형을 가지며 첫 번째는 두 개의 정수를 페이로드로 사용하고
나머지 하나는 하나의 정수만 필요로 합니다 이 모든 것 덕분에 Swift 열거형은 정말 강력하고 표현적입니다 따라서 간단하고 간결하며 가독성 높은 로직을 작성할 수 있습니다
이제 기기가 시작되었으니 USB 케이블을 분리하고 배터리로 전원을 공급할 수 있습니다
또한 이 기기를 홈 앱에서 무선으로 제어할 수 있습니다 조명을 켜 보겠습니다
그리고 꺼 보죠
밝기를 변경할 수 있는지 보겠습니다
또는 다른 색온도를 선택합니다
또는 색상을 완전히 맞춤화합니다 몇 가지 다른 것을 시도해 보죠
멋지네요, 스마트 조명의 프로토타입이 잘 작동하는군요! 성공적으로 HomeKit 지원 스마트 조명을 빌드했습니다 Embedded Swift를 사용해서요 또한 필요하다면 이 데모 프로젝트와 설정 지침을 GitHub에서 확인할 수 있습니다
HomeKit 지원 기기의 기본 프로토타입을 매우 빠르게 설정하고 실행하는 방법을 살펴봤습니다 Swift의 상호운용성 기능을 활용해서 말입니다 Swift로 전체 Matter 프로토콜을 다시 구현할 필요가 없습니다 Swift에서 기존의 구현을 사용할 수 있습니다 Swift는 코드의 깔끔하고 직관적인 디자인과 구현을 지원하며 C 및 C++보다 가독성과 안전을 향상합니다 예를 들어, 클로저를 콜백을 위한 인체공학적인 솔루션으로 사용하는 경우를 살펴봤습니다 데모에서 Embedded Swift가 어떻게 일반 Swift처럼 느껴지며 실제로 Swift의 언어 기능 대부분을 포함하는지 확인했습니다 하지만 몇 가지 차이점이 있습니다
임베디드 환경은 일반적으로 매우 제한되며 프로그램이 이에 맞도록 작고 간단한 바이너리가 필요합니다 메모리, 저장 공간, CPU 성능이 일반적으로 매우 제한됩니다 따라서 Embedded Swift는 이러한 요구 사항을 충족하기 위해 특정 기능을 허용하지 않습니다 예를 들어, 런타임 반영이 어떻게 작동하는지 고려해 보죠 한 유형의 자식을 검사하려면 해당 유형에 대한 메타데이터 레코드에 액세스해야 합니다 여기에는 필드의 이름, 오프셋 유형이 포함되며 이는 다시 다른 메타데이터 레코드를 참조하고 이런 식으로 계속됩니다 이러한 레코드가 모두 합해지면 임베디드 기기에 허용되지 않는 코드 크기 비용이 발생할 수 있죠
이를 방지하기 위해, Mirror API를 사용하는 런타임 반영은 Embedded Swift에서는 허용되지 않고 전체 Swift에서만 사용됩니다 같은 이유로, 런타임에 메타데이터가 필요하지 않도록 metatype과 ’any’ 유형 또한 허용되지 않습니다 하지만 걱정하지 마세요 대부분의 Swift 언어를 Embedded Swift에서 사용할 수 있습니다
Embedded Swift는 엄밀히 말해 전체 Swift의 하위 집합이며 배리언트나 방언이 아닙니다 따라서 Embedded Swift와 전체 Swift 사이에는 동작상의 어떠한 차이점도 없습니다 Embedded Swift에서 작동하는 모든 코드는 전체 Swift에서도 작동하죠
Embedded Swift에서 사용할 수 없는 기능을 사용하려고 하면 컴파일러가 알려 줄 것입니다 이 예제에서는 제가 any 유형을 사용하려고 했습니다
이를 방지하기 위해 이 any Countable 사용을 제네릭으로 대체할 수 있습니다 이 코드 스니펫에서는 아주 간단히 any Countable을 some Countable로 바꾸면 이 함수가 제네릭 함수로 바뀝니다 제네릭은 Embedded Swift에서 완전히 지원되며 컴파일러가 제네릭 함수를 특수화할 수 있기 때문입니다 또한 그 결과, 비용이 많이 드는 런타임 지원이나 유형 메타데이터가 필요하지 않은 코드가 작성됩니다 Embedded Swift에 대해 살펴볼 내용이 훨씬 더 많이 있습니다 Swift Evolution 프로세스의 일환으로 Embedded Swift에 대한 비전 문서가 게시되고 승인되었습니다 이 문서에서는 Embedded Swift의 상위 수준 디자인, 요구 사항 접근 방식을 설명하며 컴파일 모드와 언어 하위 집합에 대한 멋진 소개를 제공합니다 Embedded Swift를 사용해 보신다면 ’Embedded Swift -- User Manual’을 읽어 보시기 바랍니다 시작하는 방법, 기대할 사항과 기대해서는 안 되는 사항 공급업체의 SDK 및 빌드 시스템과 상호작용 시 알아야 할 세부 정보를 설명합니다 예를 들면, 사용해야 할 컴파일러 플래그와 충족해야 하는 종속성 등입니다
Embedded Swift로 작성된 예제 프로젝트 세트를 GitHub에 게시했으며 이러한 예제에서는 ARM 또는 RISC-V 마이크로컨트롤러를 탑재한 다양한 임베디드 기기를 다룹니다 여기에는 널리 사용되는 임베디드 개발 보드뿐만 아니라 Playdate 게임 콘솔 같은 기타 기기도 포함됩니다 다양한 빌드 시스템 및 통합 옵션 사용 방법도 보여 줍니다 이 내용은 Embedded Swift로 무엇을 할 수 있는지 보여 주며 여러분의 고유한 아이디어를 위한 템플릿으로 사용할 수 있습니다 임베디드 기기에서 실행되는 코드를 작성할 때에는 종종 하위 수준 하드웨어 레지스터와 상호작용해야 합니다 이와 관련하여 도움을 드리기 위해 ’Swift MMIO’를 게시했습니다 메모리 매핑된 레지스터에서의 안전하고 체계적이며 인체공학적인 작업을 위한 API를 제공하는 라이브러리입니다 마지막으로, Swift 포럼의 새로운 ’Embedded’ 하위 카테고리는 여러분이 다양한 실험, 질문 이후 토론을 수행하기에 적합한 장소입니다
지금까지 새로운 컴파일 모드인 Embedded Swift를 사용하여 임베디드 기기를 프로그래밍하는 방법을 살펴봤습니다 이 모드는 현재 미리보기로 제공되며 swift.org의 툴체인과 함께 사용하는 것이 가장 좋습니다 현재 32비트와 64비트 배리언트 모두의 ARM 및 RISC-V 칩이 지원되지만 Embedded Swift는 특정 하드웨어에 국한되지 않으며 매우 쉽게 새로운 지침 세트로 가져올 수 있습니다 Embedded Swift를 사용해 보고 멋진 전자 프로젝트를 빌드하고 Swift 포럼에서 여러분의 경험과 피드백을 공유해 주세요 시청해 주셔서 감사합니다 WWDC를 즐기세요
-
-
3:50 - Empty Embedded Swift application
@_cdecl("app_main") func app_main() { print("🏎️ Hello, Embedded Swift!") }
-
6:48 - Turning on LED to blue color
@_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) }
-
8:32 - Using an LED object
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) } } }
-
12:44 - Matter application controlling an LED light
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() }
-
18:03 - Reflection example
// Reflection needs metadata records let mirror = Mirror(reflecting: s) mirror.children.forEach { … } struct MyStruct { var count: Int var name: String }
-
18:57 - Unavailable features will produce errors
// Unavailable features will produce errors protocol Countable { var count: Int { get } } func count(countable: any Countable) { print(countable.count) }
-
19:24 - Prefer generics over “any” types
// Prefer generics over “any” types protocol Countable { var count: Int { get } } func count(countable: some Countable) { print(countable.count) }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.