How to implement IOServiceMatchingCallBack in Swift

前端 未结 3 723
执念已碎
执念已碎 2021-01-15 12:08

I would like to detect a specific USB is plugged in/removed in my application. For now, I can get the deviceName with this tutorial Working With USB Device Interfaces. But,

3条回答
  •  忘掉有多难
    2021-01-15 13:02

    It works after I put the callback function out the class. However, I don't know why.

    class IODetection {
        class func monitorUSBEvent(VendorID: Int, ProductID: Int) {
    
    
            var portIterator: io_iterator_t = 0
            var kr: kern_return_t = KERN_FAILURE
            let matchingDict = IOServiceMatching(kIOUSBDeviceClassName)
    
            // Add the VENDOR and PRODUCT IDs to the matching dictionary.
            let vendorIDString = kUSBVendorID as CFStringRef!
            let productIDString = kUSBProductID as CFStringRef!
            CFDictionarySetValue(matchingDict, unsafeAddressOf(vendorIDString), unsafeAddressOf(VendorID))
            CFDictionarySetValue(matchingDict, unsafeAddressOf(productIDString), unsafeAddressOf(ProductID))
    
            // To set up asynchronous notifications, create a notification port and add its run loop event source to the program’s run loop
            let gNotifyPort: IONotificationPortRef = IONotificationPortCreate(kIOMasterPortDefault)
            let runLoopSource: Unmanaged! = IONotificationPortGetRunLoopSource(gNotifyPort)
            let gRunLoop: CFRunLoop! = CFRunLoopGetCurrent()
    
            CFRunLoopAddSource(gRunLoop, runLoopSource.takeRetainedValue(), kCFRunLoopDefaultMode)
    
            // MARK: - USB in Notification
            let observer = UnsafeMutablePointer(unsafeAddressOf(self))
            kr = IOServiceAddMatchingNotification(gNotifyPort,
                                                  kIOMatchedNotification,
                                                  matchingDict,
                                                  deviceAdded,
                                                  observer,
                                                  &portIterator)
            deviceAdded(nil, iterator: portIterator)
    
    
            // MARK: - USB remove Notification
            kr = IOServiceAddMatchingNotification(gNotifyPort,
                                                  kIOTerminatedNotification,
                                                  matchingDict,
                                                  deviceRemoved,
                                                  observer,
                                                  &portIterator)
            deviceRemoved(nil, iterator: portIterator)
    
        }
    }
    
    func deviceAdded(refCon: UnsafeMutablePointer, iterator: io_iterator_t) -> Void {
        var kr: kern_return_t = KERN_FAILURE
    
        while case let usbDevice = IOIteratorNext(iterator) where usbDevice != 0 {
            let deviceNameAsCFString = UnsafeMutablePointer.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("Device Added: \(deviceName!)")
    
            // Do something if I get the specific device
            if deviceName == "YOUR DEVICE" {
                /// Your Action HERE
            }
    
            IOObjectRelease(usbDevice)
        }
    }
    

提交回复
热议问题