2012-03-29 24 views
2

私は接続されたジョイスティックと、Mac用の押されたボタン/軸がきれいに表示されるシンプルなアプリを作った。私はまだココアに慣れていないので、私はwebviewを使ってUIを作って、SDL Joystickライブラリを使いました。 すべてがうまくいきました。唯一の問題は、プログラムの実行中にユーザーが新しいジョイスティックを手動でスキャンして何かを接続/切断する必要があることです。HID USB/Bluetoothデバイスがココアに接続されているかどうかを知るには?

HIDデバイス、または最後にUSB/Bluetoothデバイスが接続/切断されたときに単純なコールバックを取得するにはどうすればよいですか?だから私はちょうどスキャン機能を呼び出すことができます。私は

おかげ

答えて

6

IOServiceAddMatchingNotification()と関連する機能を見てみましょう...起こって、何か新しいものがあるときにだけ知っている、デバイスを扱うか、空想何かをしたくありません。私はシリアルポート(実際にはUSBからシリアルアダプタまでの間で問題はありませんが)のコンテキストでのみ作業しましたが、IOKitのアクセス可能なデバイスにも当てはまります。私はBluetoothについてはわかりませんが、USBデバイスでは少なくとも動作するはずです。ここで私が使用したコードの抜粋です:シリアルポートは、それぞれ、システム上で利用可能になるか、削除されたときに

IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), 
       IONotificationPortGetRunLoopSource(notificationPort), 
       kCFRunLoopDefaultMode); 

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOSerialBSDServiceValue); 
CFRetain(matchingDict); // Need to use it twice and IOServiceAddMatchingNotification() consumes a reference 

CFDictionaryAddValue(matchingDict, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDRS232Type)); 

io_iterator_t portIterator = 0; 
// Register for notifications when a serial port is added to the system 
kern_return_t result = IOServiceAddMatchingNotification(notificationPort, 
                 kIOPublishNotification, 
                 matchingDictort, 
                 SerialDeviceWasAddedFunction, 
                 self,   
                 &portIterator); 
while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). 

// Also register for removal notifications 
IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), 
        IONotificationPortGetRunLoopSource(terminationNotificationPort), 
        kCFRunLoopDefaultMode); 
result = IOServiceAddMatchingNotification(terminationNotificationPort, 
              kIOTerminatedNotification, 
              matchingDict, 
              SerialPortWasRemovedFunction, 
              self,   // refCon/contextInfo 
              &portIterator); 

while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). 

マイSerialPortDeviceWasAddedFunction()SerialPortWasRemovedFunction()が呼び出されます。

関連文書is here、特に見出しGetting Notifications of Device Arrival and Departureの下にあります。

+0

うーん... 私は、両方のコールバック関数を作成し、あなたのコードを使用しようとしたいくつかのIOKitのヘッダを追加... しかし、それは未定義の参照を "ですnotificationPort "、何か不足していますか? – Rodrigo

+0

申し訳ありません。私はこのコードを既存のプロジェクトから直接コピー/ペーストしました。完全な解決策ではありませんでした。通知の取得方法の例に過ぎません。とにかく、答えのコードを更新して、runloop上でそれをスケジューリングするとともに、notificationPortの作成も含めました。このコードは、RS-232ポートの通知に固有のものです。これは一例ですが、アプリケーションに合わせて変更する必要があります。 –

+0

Andrewに感謝します。 IOServiceMatchingをkIOHIDDeviceKeyに変更し、CFDictionaryAddValue行を削除しました。しかし、一度だけ。その後、私は再び通知のために登録する必要があります、それは正しいですか? – Rodrigo

2

IOHIDManagerを使用して通知を取得します。

0

AndrewとArjunaの以前の回答に基づいて、Apple HIDデバイス(たとえば、Bluetoothトラックパッドをテスト済み)で動作するIOHIDManagerを使用して、次のスニペットが完成しました。これは、何もクリア/デクリメントする必要なく、複数回通知を送信するように見えます。

- (void) startHIDNotification 
{ 
ioHIDManager = IOHIDManagerCreate (kCFAllocatorDefault, kIOHIDManagerOptionNone ); 

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOHIDDeviceKey); 
CFDictionaryAddValue(matchingDict, CFSTR(kIOHIDManufacturerKey), CFSTR("Apple")); 

IOHIDManagerSetDeviceMatching (ioHIDManager, matchingDict); 

IOHIDManagerRegisterDeviceMatchingCallback(ioHIDManager, AppleHIDDeviceWasAddedFunction, (__bridge void *)(self)); 
IOHIDManagerRegisterDeviceRemovalCallback(ioHIDManager, AppleHIDDeviceWasRemovedFunction, (__bridge void *)(self)); 

hidNotificationRunLoop = CFRunLoopGetCurrent(); 

IOHIDManagerScheduleWithRunLoop(ioHIDManager, 
           hidNotificationRunLoop, 
           kCFRunLoopDefaultMode); 
} 

とコールバックメソッド

void AppleHIDDeviceWasAddedFunction(void *     context, 
          IOReturn    result, 
          void *     sender, 
          IOHIDDeviceRef   device) 
{ 
    NSLog(@"added"); 
} 

void AppleHIDDeviceWasRemovedFunction(void *     context, 
          IOReturn    result, 
          void *     sender, 
          IOHIDDeviceRef   device) 
{ 
    NSLog(@"removed"); 
} 
関連する問題