컴퓨터의 USB를 통해 새 장치를 꽂을 때 내 수업에 알릴 대의원이 있습니까? 내 장치에 새로운 장치가 언제 제공되는지 알고 싶습니다.스위프트의 USB 연결 대리인
답변
이 답변은 나를 위해 https://stackoverflow.com/a/35788694 일했으나 일부 특정 IOKit 부품을 가져 오기 위해 브리징 헤더를 만드는 것과 같이 약간의 수정이 필요했습니다.
먼저 IOKit.framework를 프로젝트에 추가하십시오 ("링크 된 프레임 워크 및 라이브러리"의 "+"클릭).
그런 다음 이름이 무엇이든 새로운 빈 ".m"파일을 만듭니다. 그런 다음 Xcode는 "브리징 헤더"를 만들어야하는지 묻습니다. 네 라고 말하다.
".m"파일을 무시하십시오. 엑스 코드 방금 만든 새 "YOURAPPNAME-브리징-header.h가"파일에서 다음 줄을 추가
#include <IOKit/IOKitLib.h>
#include <IOKit/usb/IOUSBLib.h>
#include <IOKit/hid/IOHIDKeys.h>
이제 링크 대답에 코드를 사용할 수 있습니다. 여기에 단순화 된 버전입니다 :
class USBDetector {
class func monitorUSBEvent() {
var portIterator: io_iterator_t = 0
let matchingDict = IOServiceMatching(kIOUSBDeviceClassName)
let gNotifyPort: IONotificationPortRef = IONotificationPortCreate(kIOMasterPortDefault)
let runLoopSource: Unmanaged<CFRunLoopSource>! = IONotificationPortGetRunLoopSource(gNotifyPort)
let gRunLoop: CFRunLoop! = CFRunLoopGetCurrent()
CFRunLoopAddSource(gRunLoop, runLoopSource.takeRetainedValue(), kCFRunLoopDefaultMode)
let observer = UnsafeMutablePointer<Void>(unsafeAddressOf(self))
_ = IOServiceAddMatchingNotification(gNotifyPort,
kIOMatchedNotification,
matchingDict,
deviceAdded,
observer,
&portIterator)
deviceAdded(nil, iterator: portIterator)
_ = IOServiceAddMatchingNotification(gNotifyPort,
kIOTerminatedNotification,
matchingDict,
deviceRemoved,
observer,
&portIterator)
deviceRemoved(nil, iterator: portIterator)
}
}
func deviceAdded(refCon: UnsafeMutablePointer<Void>, iterator: io_iterator_t) {
var kr: kern_return_t = KERN_FAILURE
while case let usbDevice = IOIteratorNext(iterator) where usbDevice != 0 {
let deviceNameAsCFString = UnsafeMutablePointer<io_name_t>.alloc(1)
defer {deviceNameAsCFString.dealloc(1)}
kr = IORegistryEntryGetName(usbDevice, UnsafeMutablePointer(deviceNameAsCFString))
if kr != KERN_SUCCESS {
deviceNameAsCFString.memory.0 = 0
}
let deviceName = String.fromCString(UnsafePointer(deviceNameAsCFString))
print("Active device: \(deviceName!)")
IOObjectRelease(usbDevice)
}
}
func deviceRemoved(refCon: UnsafeMutablePointer<Void>, iterator: io_iterator_t) {
// ...
}
참고 : deviceAdded
및 deviceRemoved
함수 (하지 방법) 할 필요가있다.
USBDetector.monitorUSBEvent()
이것은 현재 연결 장치를 나열하며, 모든 새로운 USB 장치 플러그/언 플러그 이벤트에 장치 이름을 인쇄합니다 :
은 관찰자를 시작,이 코드를 사용합니다.이것은 Swift 2.2 용으로 작성된 것인가? 나는 이것을 Swift 3에서 작동 시키려고 노력하고 있지만, 아무런 도움이되지 못합니다./변경해야 할 아이디어가 있습니까? – simonthumper
예, 신속한 3 예를 제공해주세요. 감사합니다. – Arti
나는이 질문에 현상금을 설정했습니다. 흥미로운 Swift 3 답변을 얻길 바랍니다. – Moritz
에릭 아야의 답변은 이미 훌륭하지만, 여기에 스위프트 3의 적응이 있습니다. USBWatcher
클래스의 대부분의 추악한 것들을 싸서; 이 객체의 대리자로 설정하여 알림을받습니다.
놀이터에 다음을 복사/붙여 넣기하면 작동하는지 확인할 수 있습니다. 예를 들어 장치 연결/연결 해제시 콘솔에 메시지를 기록합니다.
IOKit API가 다른 C API (예 : CoreGraphics)와 동일한 신속한 처리를받지 못해서 불행합니다. io_name_t
은 적절한 구조체가 아닌 끔찍한 튜플입니다. C 구조체는 대개 Swift로 가져옵니다. io_object_t
은 실제 참조 유형이 아니므로 ARC를 사용할 수 없습니다. 아마도 앞으로는 변경 될 것입니다. 더 나은 Swift API를보고 싶다면 file an enhancement request이어야합니다.
import Foundation
import IOKit
import IOKit.usb
public protocol USBWatcherDelegate: class {
/// Called on the main thread when a device is connected.
func deviceAdded(_ device: io_object_t)
/// Called on the main thread when a device is disconnected.
func deviceRemoved(_ device: io_object_t)
}
/// An object which observes USB devices added and removed from the system.
/// Abstracts away most of the ugliness of IOKit APIs.
public class USBWatcher {
private weak var delegate: USBWatcherDelegate?
private let notificationPort = IONotificationPortCreate(kIOMasterPortDefault)
private var addedIterator: io_iterator_t = 0
private var removedIterator: io_iterator_t = 0
public init(delegate: USBWatcherDelegate) {
self.delegate = delegate
func handleNotification(instance: UnsafeMutableRawPointer?, _ iterator: io_iterator_t) {
let watcher = Unmanaged<USBWatcher>.fromOpaque(instance!).takeUnretainedValue()
let handler: ((io_iterator_t) -> Void)?
switch iterator {
case watcher.addedIterator: handler = watcher.delegate?.deviceAdded
case watcher.removedIterator: handler = watcher.delegate?.deviceRemoved
default: assertionFailure("received unexpected IOIterator"); return
}
while case let device = IOIteratorNext(iterator), device != IO_OBJECT_NULL {
handler?(device)
IOObjectRelease(device)
}
}
let query = IOServiceMatching(kIOUSBDeviceClassName)
let opaqueSelf = Unmanaged.passUnretained(self).toOpaque()
// Watch for connected devices.
IOServiceAddMatchingNotification(
notificationPort, kIOMatchedNotification, query,
handleNotification, opaqueSelf, &addedIterator)
handleNotification(instance: opaqueSelf, addedIterator)
// Watch for disconnected devices.
IOServiceAddMatchingNotification(
notificationPort, kIOTerminatedNotification, query,
handleNotification, opaqueSelf, &removedIterator)
handleNotification(instance: opaqueSelf, removedIterator)
// Add the notification to the main run loop to receive future updates.
CFRunLoopAddSource(
CFRunLoopGetMain(),
IONotificationPortGetRunLoopSource(notificationPort).takeUnretainedValue(),
.commonModes)
}
deinit {
IOObjectRelease(addedIterator)
IOObjectRelease(removedIterator)
IONotificationPortDestroy(notificationPort)
}
}
extension io_object_t {
/// - Returns: The device's name.
func name() -> String? {
let buf = UnsafeMutablePointer<io_name_t>.allocate(capacity: 1)
defer { buf.deallocate(capacity: 1) }
return buf.withMemoryRebound(to: CChar.self, capacity: MemoryLayout<io_name_t>.size) {
if IORegistryEntryGetName(self, $0) == KERN_SUCCESS {
return String(cString: $0)
}
return nil
}
}
}
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
class Example: USBWatcherDelegate {
private var usbWatcher: USBWatcher!
init() {
usbWatcher = USBWatcher(delegate: self)
}
func deviceAdded(_ device: io_object_t) {
print("device added: \(device.name() ?? "<unknown>")")
}
func deviceRemoved(_ device: io_object_t) {
print("device removed: \(device.name() ?? "<unknown>")")
}
}
let example = Example()
멋진 대답, 덕분에 많은 편리한 작업을 위해 [USBDeviceSwift] (https://github.com/Arti3DPlayer/USBDeviceSwift) 라이브러리를 만들었습니다! 나는 예를 들어'감시자 = 관리되지 않는
@EricAya :) : 불투명 포인터 방법은 "터널"C 함수를 통해 클래스 인스턴스에 대한 참조이다. 이것은 종종 C 콜백으로 사용되며 문맥을 캡쳐 할 수없는 함수/클로저와 관련하여 사용됩니다. http://stackoverflow.com/questions/33294620/how-to-cast-self-to-unsafemutablepointervoid-type-in-swift 및 http://stackoverflow.com/ 비교 (내가 자기 광고에 대해 사과) 질문/33260808/swift-proper-of-cfnotificationcenteraddobserver-w-callback은 사용법을 보여주는 또 다른 예제입니다. –
@MartinR 그'bridge()'도우미는 매우 근사합니다! 나는 그렇게 생각하지 않았습니다. 오버로딩은 꽤 멋지게 만듭니다. IOKit.usb'와'IOKit.hid''와 편리한 작업 – jtbandes
- 1. 스위프트의 USB 장치 경로
- 2. RestKit 연결 실패 대리인
- 3. 리플렉션을 통한 일반 대리인 연결
- 4. 스위프트의 uislider 값 및 변수, 레이블 연결
- 5. 안드로이드에서 전화로 USB 연결
- 6. 안드로이드에서 USB 연결
- 7. USB 연결 문제
- 8. 프로그래밍 Usb Android와 연결
- 9. 안드로이드, 아이폰 USB 연결
- 10. Android USB 연결 상태;
- 11. 원격 USB 연결 C
- 12. USB 장치를 Android에 연결
- 13. Android-USB 연결
- 14. 킨들 USB 연결
- 15. 대리인 서명/일반 대리인?
- 16. Xcode :보기 컨트롤러와 앱 대리인 간의 연결
- 17. 리플렉션을 사용하여 이벤트에 대한 대리인 연결
- 18. linux usb 연결/연결 끊기 이벤트
- 19. Windows에 ping 5 연결 USB 연결
- 20. USB 장치 자동 감지 연결/연결 해제
- 21. 대리인
- 22. 스위프트의 튜플
- 23. 스위프트의 NSAttributedString
- 24. 스위프트의 MCOMessageFlag
- 25. 스위프트의 행렬
- 26. Android USB 호스트 - 직렬 연결?
- 27. USB 연결 iPhone 스크린 미러링
- 28. 리눅스 : USB 키보드로 직접 연결
- 29. BB10은 USB 연결 API를 지원합니까?
- 30. 대리인 및 대리인 방법이란 무엇입니까
'NSWorkspace' 볼륨 탑재 알림 사용자 정보 키를 찾으십시오. [link] (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWorkspace_Class/#//apple_ref/doc/constant_group/Volume_Mounting_Notification_User_Info_Keys) – Khundragpan
사실, 코드는 위임자가됩니다. 그 메소드는 여러 시점에서 호출 될 것입니다. – Alexander
가능한 복제본의 소유자가 무엇인지 확실하지 않습니다. http://stackoverflow.com/questions/34628464/how-to-implement-ioservicematchingcallback-in-swift/39662693 – jtbandes