从 plist 检索允许的文件类型的智能方法

发布于 2024-12-06 15:01:58 字数 2468 浏览 11 评论 0原文

场景:

我喜欢在 Cocoa 应用程序的 Info.plist 文件中定义允许的文件类型(内容类型)。因此,我添加了它们,如下例所示。

# Extract from Info.plist
[...]
<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>public.png</string>
        <key>CFBundleTypeIconFile</key>
        <string>png.icns</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSIsAppleDefaultForType</key>
        <true/>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.png</string>
        </array>
    </dict>
[...]

此外,我的应用程序允许使用 NSOpenPanel 打开文件。该面板允许通过以下选择器设置允许的文件类型:setAllowedFileTypes:文档指出可以使用 UTI

文件类型可以是常见文件扩展名或 UTI。


自定义解决方案:

我编写了以下辅助方法来从 Info.plist 文件中提取 UTI。

/**
    Returns a collection of uniform type identifiers as defined in the plist file.
    @returns A collection of UTI strings.
 */
+ (NSArray*)uniformTypeIdentifiers {
    static NSArray* contentTypes = nil;
    if (!contentTypes) {
        NSArray* documentTypes = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDocumentTypes"];
        NSMutableArray* contentTypesCollection = [NSMutableArray arrayWithCapacity:[documentTypes count]];
        for (NSDictionary* documentType in documentTypes) {
            [contentTypesCollection addObjectsFromArray:[documentType objectForKey:@"LSItemContentTypes"]];
        }
        contentTypes = [NSArray arrayWithArray:contentTypesCollection];
        contentTypesCollection = nil;
    }
    return contentTypes;
}

除了[NSBundle mainBundle]之外,还可以使用CFBundleGetInfoDictionary(CFBundleGetMainBundle())


问题:

  1. 您知道提取内容类型信息的更智能方法吗 来自 Info.plist 文件? Cocoa 有内置函数吗?
  2. 如何处理可包含的文件夹的定义 那里,例如public.folder

注意:
在我的研究过程中,我发现这篇文章内容非常丰富:简化数据处理使用统一类型标识符

Scenario:

I like to define the allowed file types (content types) in the Info.plist file of my Cocoa application. Therefore, I added them like the following example shows.

# Extract from Info.plist
[...]
<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>public.png</string>
        <key>CFBundleTypeIconFile</key>
        <string>png.icns</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSIsAppleDefaultForType</key>
        <true/>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.png</string>
        </array>
    </dict>
[...]

Further, my application allows to open files using an NSOpenPanel. The panel allows to set the allowed file types through the following selector: setAllowedFileTypes:. The documentation states that UTI can be used.

The file type can be a common file extension, or a UTI.


A custom solution:

I wrote the following helper method to extract the UTI from the Info.plist file.

/**
    Returns a collection of uniform type identifiers as defined in the plist file.
    @returns A collection of UTI strings.
 */
+ (NSArray*)uniformTypeIdentifiers {
    static NSArray* contentTypes = nil;
    if (!contentTypes) {
        NSArray* documentTypes = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDocumentTypes"];
        NSMutableArray* contentTypesCollection = [NSMutableArray arrayWithCapacity:[documentTypes count]];
        for (NSDictionary* documentType in documentTypes) {
            [contentTypesCollection addObjectsFromArray:[documentType objectForKey:@"LSItemContentTypes"]];
        }
        contentTypes = [NSArray arrayWithArray:contentTypesCollection];
        contentTypesCollection = nil;
    }
    return contentTypes;
}

Instead of [NSBundle mainBundle] also CFBundleGetInfoDictionary(CFBundleGetMainBundle()) can be used.


Questions:

  1. Do you know a smarter way to extract the content type information
    from the Info.plist file? Is there a Cocoa-build-in function?
  2. How do you deal with the definition of folders that can contained
    there, e.g. public.folder?

Note:
Throughout my research, I found this article quite informative: Simplifying Data Handling with Uniform Type Identifiers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寄人书 2024-12-13 15:01:58

以下是我从 plist 中读取信息的方法(它可以是 info.plist 或项目中的任何其他 plist,前提是您设置了正确的路径)

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *fullPath = [NSString stringWithFormat:@"%@/path/to/your/plist/my.plist", resourcePath];
NSData *plistData = [NSData dataWithContentsOfFile:fullPath];
NSDictionary *plistDictionary = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:0 errorDescription:nil];
NSArray *fileTypes = [plistDictionary objectForKey:@"CFBundleDocumentTypes"];

Here is how I read information from a plist (it can be the info.plist or any other plist you have in you project provided you set the correct path)

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *fullPath = [NSString stringWithFormat:@"%@/path/to/your/plist/my.plist", resourcePath];
NSData *plistData = [NSData dataWithContentsOfFile:fullPath];
NSDictionary *plistDictionary = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:0 errorDescription:nil];
NSArray *fileTypes = [plistDictionary objectForKey:@"CFBundleDocumentTypes"];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文