开发者

Need an API that detects when an iPhone is plugged in

I'm making an application for M开发者_运维知识库ac, and I need an API that detects when an iPhone is plugged in. Thanks.

EDIT : To clarify, specifically, I need an API that detects when an iPhone is plugged into a USB port on a Mac.


I don't have a complete answer, but a program that achieves what you want is USB Prober, supplied with Xcode and located at /Developer/Applications/Utilities/USB Prober.app. That program is open source, with the browser viewable repository being here and the whole project being included in this download. I actually found an older version to be more helpful, as available here, especially BusProbeClass.

They all rest on IOKit for which Apple's documentation seems to be very lacking in both quantity and quality.

That's heavy reading, but if you check out + USBProbe then you'll see it gets a list of current USB devices, gets IOUSBDeviceInterfaces for each in the variable deviceIntf and then pushes them to somewhere useful for the rest of the program. If you check out + outputDevice: locationID:deviceNumber: lower down in the same source file, you'll see that GetDescriptor can seemingly be used on an IOUSBDeviceDescriptor to get properties including the vendor and product ID, the combination of which is guaranteed to be unique by the USB Implementer's Forum.

Using the vendor and product ID, you can search for any specific USB device. From my Mac's System Information I can tell you that an iPhone 4 has a product ID of 0x1297 and Apple's vendor ID is 0x05ac.

Extra: from dissecting that code, if you remove a whole bunch of checks that things are succeeding and compress it all down to demonstrative stuff then the following is at least a test for whether an iPhone 4 is plugged in right now (you'll need to link to the Foundation and IOKit frameworks):

#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;
}

I haven't yet figured out how to observe for changes in plugged-in devices.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜