스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
DriverKit을 통해 iPad에 드라이버 제공
DriverKit을 통해 Thunderbolt 및 USB 액세서리를 iPad에 손쉽게 연결하는 방법을 확인하세요. 코드 변경 없이도 기존 Mac 드라이버를 변환하는 방법을 보여드리고, AudioDriverKit을 통해 실시간 오디오 지원을 추가하는 방법을 알아보며, iPad용 드라이버 개발을 위한 모범 사례 및 팁을 제공합니다.
리소스
- Communicating between a DriverKit extension and a client app
- Implementing drivers, system extensions, and kexts
- System Extensions and DriverKit
관련 비디오
WWDC21
WWDC20
-
다운로드
♪ ♪
안녕하세요, 'DriverKit를 사용해 iPad로 드라이버 가져오기'에 오신 것을 환영합니다 전 Souvik입니다 오늘은 DriverKit의 흥미있는 새 개선 사항을 다뤄보겠습니다 오늘 다룰 주제는 3가지로 먼저 DriverKit를 간략히 설명해 드릴게요 그리고 AudioDriverKit에 대한 몇 가지 업데이트를 설명하고 드라이버를 iPad로 가져오는 방법으로 마무리하겠습니다 그럼 개요부터 시작하겠습니다 2019년 Apple은 IOKit 기기 드라이버를 대체하는 DriverKit를 도입했고 DriverKit는 사용자 공간에서 실행되는 더 안정적이고 안전한 시스템을 확장하는 새로운 방법을 제시했습니다 여러분의 프로세스가 커널에 있지 않아 개발이 더 쉬웠죠 dext라고도 하는 드라이버 확장은 앱에 번들로 제공되고 Mac App Store에서도 앱과 드라이버를 쉽게 배포할 수 있어요 사람들은 검색을 통해 쉽게 드라이버를 찾을 수 있고 드라이버가 더 이상 필요하지 않다면 간단하게 앱을 삭제하여 제거할 수도 있죠 DriverKit를 도입한 후 많은 새 드라이버 제품군에 대한 지원이 늘었고 이젠 USB PCI 및 HID와 같은 전송 외에도 Networking, Block Storage Serial, Audio 그리고 SCSI 컨트롤러와 주변 기기 드라이버도 지원합니다 DriverKit로 빌드할 수 있는 드라이버 종류에 대한 자세한 내용은 WWDC 2021의 'DriverKit로 오디오 드라이버 만들기' 세션과 WWDC 2020의 'DriverKit로 PCI 및 SCSI 드라이버 현대화하기' 세션을 참고해 주세요 다음으로, 저희는 최근 중요한 몇 가지 새 기능을 AudioDriverKit에 추가했는데요 그 기능 중 하나가 바로 실시간 작업입니다 실시간 콜백을 등록할 수 있는 Audio DriverKit의 새 기능을 소개하게 되어 아주 기쁘네요 이 콜백은 IO 작업이 발생할 때마다 호출되고 실시간 스레드에서 신호 처리같은 오디오 버퍼를 수정해야 하는 경우에 사용합니다
AudioDriverKit에 실시간 콜백을 등록하기 위해서는 IOUserAudioDevice에 설정할 IOOperationHandler 블록을 선언해야 합니다 이 블록은 기기의 IOUserAudioStream 버퍼에서 IO 작업이 발생할 때 실시간 컨텍스트에서 호출됩니다
블록 내부에 어떤 작업이 있는지 확인하고 필요에 따라서 데이터를 수정할 수 있어요 끝으로 SetIOOperationHandler를 호출하여 오디오 기기의 블록을 설정합니다 이제 권한으로 넘어가 볼게요 처음 AudioDriverKit를 도입했을 때 드라이버에서는 모든 사용자 클라이언트 액세스 허용 권한을 사용해야 했어요 하지만 macOS 12.1에서는 AudioDriverKit 전용으로 새로운 권한을 도입했습니다 오디오 드라이버를 업데이트해서 모든 사용자 클라이언트 액세스 허용 권한 대신 새 오디오 제품군 권한을 사용하시기 바랍니다 모든 사용자 클라이언트 액세스 허용 권한을 유지하면 앱과 드라이버가 서로 통신할 수 있고 이 새 권한은 개발용으로 공개되어 있기 때문에 요청을 제출하지 않고 지금 바로 사용할 수 있죠 사실, 모든 DriverKit 제품군 권한을 개발에 사용할 수 있습니다 배포를 위한 권한을 요청하려면 developer.apple.com의 System Extension 페이지를 방문해 보세요 다음으로 iPad용 DriverKit를 소개하게 되어 정말 신나는군요 더 많은 전문가가 최고의 작업을 위해 iPad를 사용하고 있지만 많은 분이 iPad에서 사용 불가한 외부 하드웨어에 의존하고 있어요 그래서 이 DriverKit의 iPad용 출시 소식을 전하게 되어 기쁩니다
macOS의 DriverKit를 사용하면 시스템을 안전하게 확장할 수 있고 iPad에도 동일한 기술을 적용할 수 있습니다 사실, 이미 Mac에서 DriverKit를 사용하여 드라이버를 생성했다면 이를 변경하지 않고도 완전 동일한 드라이버를 iPad로 가져올 수 있어요 USB, PCI 및 Audio의 경우 iPadOS 16에서 지원되고 이제 처음으로 iPad 및 더 많은 기기에서 Thunderbolt 오디오 인터페이스를 사용할 수 있겠죠 이건 다 M1 칩 덕분이죠 M1이 탑재된 모든 iPad는 DriverKit를 지원하고 iPadOS의 DriverKit는 macOS와 동일하며 이건 하나의 DriverKit 드라이버를 빌드하여 두 플랫폼 모두에서 작동되며 소스를 변경할 필요가 없다는 것을 의미합니다 또한 Xcode 14의 새로운 다중 플랫폼 앱 기능을 사용하면 단일 앱 타깃 생성이 쉬워져 Mac과 iPad 모두에서 드라이버를 제공할 수 있죠 멀티플랫폼 앱에 대한 자세한 내용은 'Xcode를 사용하여 멀티플랫폼 앱 개발하기' 세션을 확인하세요
Xcode는 이제 DriverKit 드라이버 자동 서명도 지원하는데 iPadOS에서도 DriverKit를 처리할 수 있고 Mac과 iPad 모두 프로비저닝이 가능합니다 더는 DriverKit 드라이버에 대한 수동 서명을 구성할 필요가 없어요 iPadOS 앱과 드라이버는 macOS와 마찬가지로 App Store에서 배포할 수 있어요 즉, 앱 내 구입과 같은 기능을 활용하고 사용자가 드라이버를 쉽게 찾을 수 있죠 기존 macOS 드라이버와 앱을 iPad로 가져오는게 얼마나 쉬운지 한 번 확인해 보겠습니다 여기 DriverKitSampleApp이라는 앱이 있는데 여기에는 레이블이 있는 SwiftUI 보기와 사용자가 드라이버를 설치할 수 있는 버튼이 있어요 이 드라이버는 NullDriver이고 드라이버가 시작되면 메시지를 프린트하고 매초 타이머를 시작하여 timerCount라는 카운터를 증가시킵니다 이것을 iPad 앱으로 만들려면 Xcode에서 DriverKitSampleApp 타깃을 선택하면 되는데요
Supported Destinations에 iPad를 추가하면
이제 실행 대상을 Mac에 연결한 iPad로 변경할 수 있어요
이제 iPad에서 실행해 볼게요 여기 iPad 앱이 있고 Xcode에서 본 뷰의 레이블과 버튼이 있습니다 Install Dext 버튼을 탭하면 이 새로운 Drivers 링크가 표시되는 Settings로 이동하게 됩니다 이 링크를 탭하면 앱에 번들로 제공되는 모든 드라이버 목록이 표시되고 이제 Null Driver를 활성화할 수 있습니다 이미 데모에서 몇 가지 발견한 부분이 있겠지만 Null Driver는 iPadOS 앱에 번들로 제공되며 설치 후 시스템에서 자동으로 검색됩니다 macOS에서는 SystemExtension 프레임워크를 사용하여 사용자에게 드라이버를 설치하라는 메시지를 보여줘야 하는데 iPadOS에는 SystemExtensions 프레임워크가 없습니다
Xcode 내부에는 앱에 드라이버가 포함되어있죠 드라이버는 저수준 소프트웨어이고 권한이 있기 때문에 실행 전에 사용자가 승인해야 합니다 macOS에서 사용자는 Security & Privacy로 이동하여 시스템을 확장해야 하고 iPadOS에서 드라이버 승인은 Settings 앱에서 가능합니다 드라이버 승인에는 두 가지 방법이 있어요 드라이버가 설치된 앱이 하나 이상 있는 경우라면 사용 가능한 모든 드라이버 목록이 있는 General Settings 메뉴에서 각 드라이버를 켜고 끌 수 있습니다 만약 앱에 Settings 번들이 포함된 경우라면 앱의 Settings 내부에 Drivers 링크를 사용합니다 Settings에는 드라이버를 활성화하라는 메시지가 꼭 나타나야 합니다 그러니 macOS 드라이버 프로젝트로 다시 시작하여 Settings에서 드라이버를 활성화하라는 메시지를 표시하는 방법을 살펴볼게요 먼저 지원 대상에 iPad를 추가합니다
SwiftUI 보기에는 드라이버를 설치하는 버튼이 있고 보기 모델에는 SystemExtensions 프레임워크와 상호 작용하는 상태 머신이 있습니다 이 프로젝트 Mac과 iPad용으로 빌드될 예정이기 때문에 Mac 보기 및 보기 모델을 가지고 있지만 iPad에서 사용할 새 보기도 만들고자 합니다
그런 다음 Build Phases 및 Compile sources로 이동하여 iOS 또는 macOS용으로 조건부 컴파일하도록 각 파일에 대한 플랫폼 필터를 변경합니다
이제 Settings 번들을 추가해 볼게요 지금은 기본 예시의 Settings를 사용하지만 나중에 앱에서 사용할 실제 Settings로 변경할 수 있어요
이제 방금 만든 iOS 보기를 확인해 볼게요 가장 먼저 macOS 보기를 iOS 보기로 복사해 볼게요
iOS 보기는 보기 모델을 사용하지 않기 때문에 이건 없어도 됩니다
또한 Settings 번들을 열려면 버튼 동작을 변경해야 하는데 그럼 사용자가 Settings로 이동해 드라이버를 활성화할 수 있죠
마지막으로 사용자가 설정에서 드라이버를 활성화하기 위해 버튼 텍스트를 변경하겠습니다
이제 실행해 볼게요 디자인한 보기도 있고 버튼을 탭하면 Settings 번들로 이동합니다 그런 다음 드라이버로 이동하여 Null 드라이버를 활성화합니다
드라이버는 주문형으로 출시된다는 점을 꼭 잊지 마세요 비록 Settings에서 드라이버를 활성화했지만 드라이버는 하드웨어 기기가 iPad에 연결되어 있을 때만 실행됩니다 드라이버가 실행되면 Xcode 무선 디버깅을 사용하면 디버거를 연결할 수 있어요 그렇게 하려면 Xcode의 디버그 메뉴로 이동하여 프로세스에 연결한 다음 NullDriver 프로세스를 선택합니다 일단 연결되면 중단점을 설정하거나 실행을 멈출 수 있어요 제가 여기 타이머에 중단점을 설정했는데 타이머가 호출된 횟수를 확인하기 위해 timerCount를 프린트할게요
디버깅이 완료되면 Xcode의 Debug 메뉴를 사용하여 드라이버 프로세스에서 분리합니다
이제 드라이버가 생겼어요 하지만 드라이버 그 자체로는 별로 유용하지 않아요 드라이버는 시스템의 나머지 부분과 통신해야 합니다 AudioDriverKit와 같은 일부 DriverKit 프레임워크가 이를 처리하지만 하드웨어에 대한 사용자 지정 제어판 앱을 만드는 것과 같은 고급 작업을 수행해야 하는 경우에는 앱이 드라이버와 통신할 수 있게 설정해야 합니다 이건 사용자 클라이언트를 통해 가능한 작업인데 이렇게 하면 앱과 드라이버 통신을 허용하는 고유한 인터페이스를 정의할 수 있어요 앱은 IOKit.framework를 사용하여 사용자 클라이언트를 열고 어떻게 작동하는지는 developer.apple.com의 예시 코드를 참고해 주세요
저희는 앱이 드라이버와 통신할 수 있다는 것을 알지만 그래도 보안을 잊어서는 안 되겠죠 드라이버는 권한이 있으므로 우린 모든 앱이 드라이버와 통신하는 것을 원치 않습니다
macOS에서 앱은 driverkit userclient-access 권한이 필요하고 여기서 값은 허용되는 드라이버 번들 식별자의 배열입니다
iPadOS에 Communicates With Drivers라는 새 권한을 추가하는데 이건 macOS 사용자 클라이언트 권한을 대체하죠 이 권한을 통해 앱은 드라이버에서 사용자 클라이언트를 열 수 있습니다
XML 권한 문자열을 사용하면 Communicates With Drivers 권한을 앱에 수동으로 추가할 수 있어요
Xcode에서 이 권한을 추가할 수도 있습니다 Xcode에서 Signing and Capabilities으로 이동한 다음 새 기능을 추가합니다 그런 다음 'communicates with drivers'을 검색하면 앱에 기능을 추가할 수 있어요
사용자 클라이언트는 다른 개발자의 앱과 여러분의 드라이버가 상호 작용하는 데 쓰이기도 하는데요 예를 들어 여러분의 앱과 드라이버를 다른 개발자의 앱에 제공한다고 가정해볼게요 DriverKit 사용자 클라이언트도 이를 지원할 수 있습니다
드라이버와 통신해야 하는 각 앱은 통신을 할 권한이 필요합니다 드라이버에는 Allow Third Party User Clients 권한이 필요하고 이를 통해 다른 팀 식별자로 빌드된 앱이 드라이버에 대한 사용자 클라이언트를 열 수 있죠 이 권한이 없으면 같은 팀의 앱과 드라이버만 통신할 수 있어요 Allow Third Party User Clients 권한을 수동으로 드라이버에 추가하려면 XML 권한 문자열을 사용하면 됩니다 아니면 드라이버의 Xcode의 Signing and Capabilities 메뉴에 들어가 이 기능을 추가할 수도 있죠
이러한 새로운 사용자 클라이언트 권한은 개발을 위해 공개되어 있기 때문에 승인 없이 바로 사용할 수 있어요 배포를 위해 이러한 권한을 요청하려면 개발자 웹 사이트를 확인해 보시면 됩니다 DriverKit 드라이버는 앱 업데이트에도 큰 영향을 주는데요 자동 앱 업데이트는 사용자에게 항상 최신 버전의 앱을 제공하지만 드라이버가 포함된 앱은 업데이트 프로세스가 약간 다릅니다 앱 스토어에 첫 번째 버전의 앱을 배포한다고 가정해 볼게요 그리고 번들 드라이버와 해당 앱을 iPad에 설치하고 Settings에서 드라이버를 활성화합니다 드라이버용 하드웨어 기기를 연결하면 드라이버가 실행되고 그럼 앱이 사용자 클라이언트를 통해 드라이버와의 통신을 시작할 수 있습니다 이제 앱에 버그가 있어서 App Store에 버전 2를 제출한다고 가정해 보겠습니다 자동 앱 업데이트 때문에 버전 2 앱이 다운로드되고 iPad에 자동으로 설치가 될 거예요 드라이버 승인 상태는 업데이트를 통해 유지되기 때문에 드라이버를 재승인할 필요가 없어요 하지만 하드웨어가 여전히 연결되어 있고 버전 1의 드라이버가 계속 실행되고 있습니다 앱 업데이트가 되면서 드라이버 버전 2도 다운로드됐지만 실행은 안 되는 거죠 이전 드라이버가 실행되기 때문에 버전 2 앱이 버전 1 드라이버와 통신해야 하는 경우죠
하드웨어 기기 연결을 끊으면 드라이버는 작동하지 않고 그럼 드라이버 버전 1은 멈추게 되며 버전 2의 드라이버가 업데이트됩니다
이제 기기를 다시 연결하면 버전 2의 드라이버가 실행되고 앱과 새 드라이버가 통신하게 됩니다
요약하자면 앱은 자동 앱 업데이트를 통해 업데이트되고 드라이버는 기기 연결을 끊어야 업데이트가 됩니다 그리고 앱은 이전 드라이버와 통신할 수도 있어요 앱과 드라이버가 준비되었다면 이제 App Store에 제출해 보세요 드라이버는 DriverKit를 지원하는 기기에서만 실행할 수 있고 만약 드라이버만 설치하는 경우처럼 앱을 해당 기기에만 제한하려면 DriverKit를 앱의 UIRequiredDeviceCapabilities에 추가하세요 이렇게 하면 DriverKit를 지원하지 않는 기기에 앱을 설치할 수 없습니다 더불어 앱과 드라이버가 어떻게 하드웨어 창치에서 작동하는지를 보여주는 비디오를 App Review에 제출하는 것을 추천해 드려요 이상 iPad의 DriverKit를 살펴봤습니다 이제 M1을 사용해 USB, PCI 및 Audio 드라이버를 iPad로 가져와 App Store의 앱에서 드라이버를 제공할 수 있어요 이미 드라이버가 있어도 쉽게 iPad로 가져올 수 있습니다 개발자가 iPad에서 DriverKit를 사용해 보고 피드백 지원을 통해 피드백을 제공하는 것도 권장합니다 시청해 주셔서 감사합니다
-
-
2:25 - Register real-time callback in AudioDriverKit
// Declare a IOOperationHandler block to set on the IOUserAudioDevice. // The block will be called from a real time context when a i/o operation // occurs on the IOUserAudioStream buffers for the device. io_operation = ^kern_return_t(IOUserAudioObjectID in_device, IOUserAudioIOOperation in_io_operation, uint32_t in_io_buffer_frame_size, uint64_t in_sample_time, uint64_t in_host_time) { // Add custom code to make modifications to the buffers as necessary if (in_io_operation == IOUserAudioIOOperationWriteEnd) { ... } else if (in_io_operation == IOUserAudioIOOperationBeginRead) { ... } return kIOReturnSuccess; }; this->SetIOOperationHandler(io_operation);
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.