Is there a way of getting a Mac's icon given its model number?

前端 未结 3 1428
心在旅途
心在旅途 2020-12-04 01:50

I know you can get the current machine\'s icon from cocoa using the following code:

NSImage *machineIcon = [NSImage imageNamed:NSImageNameComputer];
<         


        
3条回答
  •  情歌与酒
    2020-12-04 02:34

    It is possible to programmatically convert model identifiers to images without using private frameworks. This code works on at least OS X 10.4 and later.

     + (NSImage*)imageForMachineModel:(NSString*)machineModel
     {
         NSImage* image = nil;
    
         NSString* uti = NULL;
         if ((machineModel != nil) &&
             ([machineModel length] > 0))
         {
             NSString* fixedModel = [NSString stringWithUTF8String:machineModel.UTF8String];
             uti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(CFSTR("com.apple.device-model-code"),(__bridge CFStringRef)fixedModel,NULL);
         }
         else
         {
             // Default to a generic Mac image for null
             uti = (__bridge_transfer NSString*) CFStringCreateCopy(kCFAllocatorDefault,CFSTR("com.apple.mac"));
         }
    
         if (uti != NULL)
         {
             CFDictionaryRef utiDecl = UTTypeCopyDeclaration((__bridge CFStringRef)(uti));
             if (utiDecl != NULL)
             {
                 CFStringRef iconFileName = CFDictionaryGetValue(utiDecl,CFSTR("UTTypeIconFile"));
                 if (iconFileName == NULL)
                 {
                     while((iconFileName == NULL) &&
                           (utiDecl != NULL) &&
                           (uti != NULL))
                     {
                         // BUG: macOS 10.12 may return string or array of strings; unchecked in this implementation!
                         uti = NULL;
                         uti = CFDictionaryGetValue(utiDecl,CFSTR("UTTypeConformsTo"));
                         if (uti != NULL)
                         {
                             CFRelease(utiDecl);
                             utiDecl = NULL;
                             utiDecl = UTTypeCopyDeclaration((__bridge CFStringRef)(uti));
                             if (utiDecl != NULL)
                             {
                                 iconFileName = CFDictionaryGetValue(utiDecl,CFSTR("UTTypeIconFile"));
                             }
                         }
                     }
                 }
    
                 if (iconFileName != NULL)
                 {
                     CFURLRef bundleURL = UTTypeCopyDeclaringBundleURL((__bridge CFStringRef)(uti));
                     if (bundleURL != NULL)
                     {
                         NSBundle* bundle = [NSBundle bundleWithPath:[(__bridge NSURL*)bundleURL path]];
                         if (bundle != nil)
                         {
                             NSString* iconPath = [bundle pathForResource:(__bridge NSString*)iconFileName ofType:nil];
                             if (iconPath != nil)
                             {
                                 image = [[NSImage alloc] initWithContentsOfFile:iconPath];
                             }
                         }
                         CFRelease(bundleURL);
                     }
                 }
    
                 if (utiDecl != NULL)
                 {
                     CFRelease(utiDecl);
                 }
             }
         }
    
         if (image == nil)
         {
             // Do something sensible if no image found
         }
    
         return image;
     }
    

    Be aware there is currently a bug rdr://27883672 in macOS 10.12 beta 6 that crashes within UTTypeCopyDeclaration. This is because UTTypeConformsTo may return either a CFStringRef or CFArrayRef of CFStringRef. The code snippet assumes only a CFStringRef will ever be returned.

    Adapt for Sandboxing

    To use this code with sandboxing, avoid directly loading the icon file. Instead get the UTTypeIdentifier from utiDecl and pass that to NSWorkspace's iconForFileType.

提交回复
热议问题