如何使用Swift在OS X上阅读Finder图标(左侧源列表)

时间:2015-07-31 22:59:30

标签: macos swift cocoa

我尝试阅读有关左侧源列表中的finder中显示的图标的信息。我已尝试使用以下选项NSFileManager

  • NSURLEffectiveIconKey图标读取与finder中的不同
  • NSURLCustomIconKey - 返回nil
  • NSURLThumbnailKey - 返回nil
  • NSThumbnail1024x1024SizeKey - 返回nil

我设法使用NSFileManager读取所有已安装的设备,但我不知道如何读取与设备连接的图标?也许某人有任何想法或暗示。

我也尝试使用

var image: NSImage = NSWorkspace.sharedWorkspace().iconForFile((url as! NSURL).path!)

但它返回的图像与NSURLEffectiveIconKey

相同

谢谢!

3 个答案:

答案 0 :(得分:7)

首先,查询Finder侧边栏中显示哪些卷的正确方法是使用LSSharedFileList API。该API还提供了查询图标的方法:

LSSharedFileListRef list = LSSharedFileListCreate(NULL, kLSSharedFileListFavoriteVolumes, NULL);
UInt32 seed;
NSArray* items = CFBridgingRelease(LSSharedFileListCopySnapshot(list, &seed));
CFRelease(list);
for (id item in items)
{
    IconRef icon = LSSharedFileListItemCopyIconRef((__bridge LSSharedFileListItemRef)item);
    NSImage* image = [[NSImage alloc] initWithIconRef:icon];

    // Do something with this item and icon

    ReleaseIconRef(icon);
}

您可以使用LSSharedFileListItemCopyDisplayName()LSSharedFileListItemCopyResolvedURLLSSharedFileListItemCopyProperty()查询项目的其他属性。

答案 1 :(得分:3)

这个答案是对Ken Thomases's Objective-C answer的Swift 1.2的翻译。

所有学分都归Ken Thomases所有,这只是他精彩答案的翻译。

let listBase = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListFavoriteVolumes.takeUnretainedValue(), NSMutableDictionary())
let list = listBase.takeRetainedValue() as LSSharedFileList

var seed:UInt32 = 0
let itemsCF = LSSharedFileListCopySnapshot(list, &seed)

if let items = itemsCF.takeRetainedValue() as? [LSSharedFileListItemRef] {
    for item in items {
        let icon = LSSharedFileListItemCopyIconRef(item)
        let image = NSImage(iconRef: icon)
        // use image ...
    }
}

说明:

在翻译Ken的Objective-C答案时尝试使用它我遇到了一些困难,这就是我做出这个答案的原因。

第一个问题是LSSharedFileListCreate,Swift中的方法签名并不接受nil作为其第一个参数。我必须找到代表CFAllocatorkCFAllocatorDefault的常量。第三个参数也没有接受nil,所以我放了一个虚拟的未使用的NSMutableDictionary来保持编译器满意。

"种子" LSSharedFileListCopySnapshot的参数不接受inout的常规var seed:Uint32?,我必须为seed提供默认值。

在决定使用这些API时何时使用takeRetainedValuetakeUnRetainedValue我提到this answer

最后,我不得不将返回的数组转换为LSSharedFileListItemRef元素的Swift数组(最初由编译器推断为CFArray)。

<强>更新

OS X El Capitan 10.11(感谢@patmar)

已弃用此功能

enter image description here

更新2

请注意,虽然它已被弃用,但仍然有效。现在忽略了先前解决方案中的演员[LSSharedFileListItemRef],因此我们必须转换为NSArray,然后再投射该项目:

if let items = itemsCF.takeRetainedValue() as? NSArray {
    for item in items {
        let icon = LSSharedFileListItemCopyIconRef(item as! LSSharedFileListItem)
        let image = NSImage(iconRef: icon)
        // use image ...

    }
}

答案 2 :(得分:0)

NSURLCustomIconKey将返回nil,因为未实现对此密钥的支持。它在标题中提到,但在NSURL文档中没有。您可以通过弃用的文件管理器方法获取信息。

https://developer.apple.com/library/mac/documentation/Carbon/Reference/File_Manager/

或许可能是这样的。

func getResourceValue(_ value: AutoreleasingUnsafeMutablePointer<AnyObject?>,
           forKey key: String,
            error error: NSErrorPointer) -> Bool

参数

应存储由key标识的资源属性的值的位置 密钥
URL的资源属性之一的名称 的错误
无法检索资源值时发生的错误。此参数是可选的。如果您对收到错误信息不感兴趣,可以传递nil。