Нужен API, который определяет, когда iPhone подключен - PullRequest
3 голосов
/ 04 сентября 2011

Я делаю приложение для Mac, и мне нужен API, который определяет, когда iPhone подключен. Спасибо.

РЕДАКТИРОВАТЬ: Чтобы уточнить, в частности, мне нужен API, который определяет, когда iPhone подключен к USB-порту на Mac.

1 Ответ

6 голосов
/ 05 сентября 2011

У меня нет полного ответа, но программа, которая достигает того, что вы хотите, - это USB Prober, поставляется с Xcode и расположена по адресу /Developer/Applications/Utilities/USB Prober.app. Эта программа с открытым исходным кодом, с видимым в браузере репозиторием здесь и всем проектом, включенным в этой загрузки . Я действительно нашел более старую версию более полезной, так как она доступна здесь , особенно BusProbeClass .

Все они опираются на IOKit, для которого документация Apple, похоже, очень не хватает ни по количеству, ни по качеству.

Это тяжелое чтение, но если вы посмотрите + USBProbe, то увидите, что он получает список текущих USB-устройств, получает IOUSBDeviceInterface с для каждого в переменной deviceIntf, а затем отправляет их куда-то, что полезно для остальная часть программы. Если вы отметите + outputDevice: locationID:deviceNumber: ниже в том же исходном файле, вы увидите, что GetDescriptor может использоваться на IOUSBDeviceDescriptor для получения свойств, включая идентификатор поставщика и продукта, комбинация которых гарантированно будет уникальны для форума разработчиков USB.

Используя поставщика и идентификатор продукта, вы можете искать любое конкретное USB-устройство. Из информации о системе моего Mac я могу сказать, что iPhone 4 имеет идентификатор продукта 0x1297 и идентификатор производителя Apple 0x05ac.

Дополнительно: от разбора этого кода, если вы удалите целую кучу проверок, что все работает успешно, и сожмете все это до демонстративного материала, то следующее - это по крайней мере проверка того, подключен ли сейчас iPhone 4 Нужно будет связать со структурой Foundation и IOKit):

#include <stdio.h>
#import <Foundation/Foundation.h>
#import <IOKit/usb/IOUSBLib.h>
#import <IOKit/IOCFPlugIn.h>
#import <mach/mach_port.h>

int main (int argc, const char * argv[])
{
    // get the port through which to talk to the kernel
    mach_port_t masterDevicePort;
    IOMasterPort(MACH_PORT_NULL, &masterDevicePort);

    // create a dictionary that describes a search
    // for services provided by USB
    CFDictionaryRef matchingDictionary = IOServiceMatching(kIOUSBDeviceClassName);

    // get an iterator for all devices that match
    // the dictionary
    io_iterator_t deviceIterator;
    IOServiceGetMatchingServices(
            masterDevicePort,
            matchingDictionary,
            &deviceIterator);

    // iterate through the iterator...
    io_service_t ioDevice;
    while((ioDevice = IOIteratorNext(deviceIterator)))
    {
        IOUSBDeviceInterface **deviceInterface = NULL;
        IOCFPlugInInterface **ioPlugin = NULL;
        SInt32 score;

        // get a pointer to the device, stored to ioPlugin
        IOCreatePlugInInterfaceForService(
            ioDevice,
            kIOUSBDeviceUserClientTypeID,
            kIOCFPlugInInterfaceID,
            &ioPlugin,
            &score);

        // ask the device for its interface
        (*ioPlugin)->QueryInterface(
            ioPlugin, 
            CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
            (void *)&deviceInterface);

        // make and issue a request to get the device descriptor
        IOUSBDeviceDescriptor deviceDescriptor;
        IOUSBDevRequest request;

        request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
        request.bRequest = kUSBRqGetDescriptor;
        request.wValue = kUSBDeviceDesc << 8;
        request.wIndex = 0;
        request.wLength = sizeof(deviceDescriptor);
        request.pData = &deviceDescriptor;

        (*deviceInterface)->DeviceRequest(deviceInterface, &request);

        // now we have the device descriptor, do a little cleaning up -
        // release the interface and the device
        (*deviceInterface)->Release(deviceInterface);
        IOObjectRelease(ioDevice);

        // ensure that the values returned are in the appropriate
        // byte order for this platform
        CFSwapInt16LittleToHost(deviceDescriptor.idVendor);
        CFSwapInt16LittleToHost(deviceDescriptor.idProduct);

        // check whether we have an iPhone 4 attached
        if(deviceDescriptor.idVendor == 0x05ac && deviceDescriptor.idProduct == 0x1297)
            printf("iPhone 4 is connected!");
    }

    // clean up by releasing the device iterator
    // and returning the communications port
    IOObjectRelease(deviceIterator);
    mach_port_deallocate(mach_task_self(), masterDevicePort);

    return 0;
}

Я еще не понял, как наблюдать за изменениями в подключенных устройствах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...