Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?
Forum>Entwickler>Mit Cocoa und IOKit erkennen, ob der Mac mit einem Force Touch-fähigen Gerät verbunden ist

Mit Cocoa und IOKit erkennen, ob der Mac mit einem Force Touch-fähigen Gerät verbunden ist

oddysseey
oddysseey17.11.1514:56
Hallo, liebe Entwickler

Nachdem ich es endlich geschafft habe, Force Touch Events in einem NSTableView abzufangen () und weiterzuverwenden (was sich übrigens schwerer herausgestellt hat, als es hätte sein müssen), bin ich jetzt auch endlich darauf gekommen, wie ich erkennen kann, ob der Mac, auf dem meine App läuft, über ein Trackpad verfügt, das Force Touch-fähig ist.

Der Code besteht aus zwei Methoden:
/*
 SOURCE CODE LICENSE
 
 1) You can use the code in your own products.
 2) You can modify the code as you wish, and use the modified code in your products.
 3) You can redistribute the original, unmodified code, but you have to include the full license text below.
 4) You can redistribute the modified code as you wish (without the full license text below).
 5) In all cases, you must include a credit mentioning Matthias Gansrigler as the original author of the source.
 6) I’m not liable for anything you do with the code, no matter what. So be sensible.
 7) You can’t use my name or other marks to promote your products based on the code.
 8) If you agree to all of that, go ahead and download the source. Otherwise, don’t.
 
 Contact: Matthias Gansrigler || opensource@eternalstorms.at ||  http://eternalstorms.at || @eternalstorms on twitter
 
 This NSApplication Category is available on Github at: https://github.com/eternalstorms/NSBeginAlertSheet-using-Blocks
 */

+ (BOOL)isForceTouchCapable
{
    if (![[self class] isAtLeastElCapitan])
        return NO;

    io_iterator_t iterator;

    //get default HIDDevice dictionary
    CFMutableDictionaryRef mDict = IOServiceMatching(kIOHIDDeviceKey);

    //add manufacturer "Apple Inc." to dict
    CFDictionaryAddValue(mDict, CFSTR(kIOHIDManufacturerKey), CFSTR("Apple Inc."));

    //get matching services, depending on dict
    IOReturn ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, mDict, &iterator);

    BOOL result = YES;
    if (ioReturnValue != kIOReturnSuccess)
        NSLog(@"error getting matching services for force touch devices");
    else
    {
        //recursively go through each device found and its children and grandchildren, etc.
        result = [[self class] _containsForceTouchDevice:iterator];
        IOObjectRelease(iterator);
    }

    return result;
}

+ (BOOL)_containsForceTouchDevice:(io_iterator_t)iterator
{
    io_object_t object = 0;
    BOOL success = NO;
    while ((object = IOIteratorNext(iterator)))
    {
        CFMutableDictionaryRef result = NULL;
        kern_return_t state = IORegistryEntryCreateCFProperties(object, &result, kCFAllocatorDefault, 0);
        if (state == KERN_SUCCESS && result != NULL)
        {
            if (CFDictionaryContainsKey(result, CFSTR("DefaultMultitouchProperties")))
            {
                CFDictionaryRef dict = CFDictionaryGetValue(result, CFSTR("DefaultMultitouchProperties"));
                CFTypeRef val = NULL;
                if (CFDictionaryGetValueIfPresent(dict, CFSTR("ForceSupported"), &val))
                {
                    Boolean aBool = CFBooleanGetValue(val);
                    if (aBool) //supported
                        success = YES;
                }
            }
        }

        if (result != NULL)
            CFRelease(result);

        if (success)
        {
            IOObjectRelease(object);
            break;
        } else
        {
            io_iterator_t childIterator = 0;
            kern_return_t err = IORegistryEntryGetChildIterator(object, kIOServicePlane, &childIterator);
            if (!err)
            {
                success = [[self class] _containsForceTouchDevice:childIterator];
                IOObjectRelease(childIterator);
            } else
                success = NO;

            IOObjectRelease(object);
        }
    }

    return success;
}
Jetzt muss man nur + (BOOL)isForceTouchCapable; aufrufen, um YES (ja, der Mac ist mit einem Force Touch-fähigen Trackpad verbunden) oder NO (der Mac ist nicht mit einem solchen Gerät verbunden) zurückzuerhalten.

Einen detaillierteren Blick auf den Code werfe ich auf meinem Blog (), zusammen mit einem Beispiel-Projekt, das Ihr auch hier direkt herunterladen () könnt.

Ich hoffe, der Code kann euch von Nutzen sein!

Alles Gute und Happy Coding ,
Matthias
„Eternal Storms Software - Apps Crafted with Care“
0

Kommentare

matt.ludwig17.11.1520:57
oddysseey

Den Like hast du schon im Forum bekommen danke nochmals
0

Kommentieren

Diese Diskussion ist bereits mehr als 3 Monate alt und kann daher nicht mehr kommentiert werden.