如何检查具有给定扩展名的目录是否显示为Finder作为包? [英] How to check whether directories with a given extension are shown by the Finder as a package?

查看:126
本文介绍了如何检查具有给定扩展名的目录是否显示为Finder作为包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于给定的扩展程序,如何检查具有该扩展名的目录是否将作为包显示在Finder中?



我认为以下方法是有效的实现这一点,但创建一个临时目录感觉像一个黑客。我想我应该能够通过启动服务API ,但我不知道该怎么做(我可能会忽略明显的)。

  // NSWorkspace的扩展方法
@implementation NSWorkspace(MyExtraMethods)
- (BOOL)isPackageExtension:(NSString *)extension
{
NSString * pathToTemp = [NSTemporaryDirectory()stringByAppendingPathComponent:[@UntitledstringByAppendingPathExtension:extension]];
[[NSFileManager defaultManager] createDirectoryAtPath:pathToTemp withIntermediateDirectories:NO attributes:nil error:NULL];
BOOL result = [[NSWorkspace sharedWorkspace] isFilePackageAtPath:pathToTemp];
[[NSFileManager defaultManager] removeItemAtPath:pathToTemp error:NULL];
return result;
}
@end

//上面的基本测试
- (void)testIsPackageExtension
{
STAssertFalse([[NSWorkspace sharedWorkspace ] isPackageExtension:@txt],@);
STAssertFalse([[NSWorkspace sharedWorkspace] isPackageExtension:@rtf],@);

STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@rtfd],@);
STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@app],@);
STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@kext],@);
STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@clr],@);

/ *以下测试取决于安装的应用程序
,不包括在Mac OS X中:
.esproj Espresso,测试版本为2.0.5(http:// macbabbit.com/espresso/)
.dtps仪器,包含在Xcode中,使用版本4.5(4523)测试* /
STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@esproj],@ );
STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension:@dtps],@);
}

编辑:包含附加的示例扩展(原始发布仅使用rtf和rtfd)。

解决方案

=http://developer.apple.com/library/ios/#documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html =nofollow>您的扩展程序的统一类型标识符信息 。

首先必须找出正确的UTI,然后测试它是否符合 com.apple.package (被声明为kUTTypePackage):

   - (BOOL)isPackageTypeForExtension:(NSString *)extension 
{
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension ,(__bridge CFStringRef)(extension),NULL);
return UTTypeConformsTo(UTI,kUTTypePackage);
}

更新:

此外,您可以检查kUTTypeBundle:

  UTTypeConformsTo(UTI,kUTTypeBundle)
pre>

OR(|)将结果写入上述方法的返回值。



以下Apple文档描述了如何为基于文档的应用程序(通常使用NSFileWrappers和文档包)定义UTI:
https://developer.apple。 com / library / mac / documentation / DataManagement / Conceptual / DocBasedAppProgrammingGuideForOSX / ApplicationCreationProcess / ApplicationCreationProcess.html#// apple_ref / doc / uid / TP40011179-CH6-997699



Update2:

除了符合kUTTypePackage或kUTTypeBundle的UTI之外,还有一个软件包位文件属性,也可以将文件夹标记为软件包:



Apple的文档


系统如何识别软件包和软件包Finder将
目录视为如果以下条件中的任何一个为真,则包:




  • 目录具有已知的文件扩展名:.app,.bundle,
    .framework,.plugin,.kext等。

  • 该目录具有扩展名
    ,其他一些应用程序声明表示包类型;请参阅
    文件包。

  • 目录已设置其包位。


Update3:

上述基于UTI的方法并不包括Finder在测试文件夹时考虑的所有情况是包或包。

它可用于测试特定的UTI是否符合kUTTypeBundle或kUTTypePackage。


For a given extension, how do you check whether directories with that extension will be shown by the Finder as a package?

I figured the method below is an effective implementation for this, but creating a temporary directory feels like a hack. I'm guessing I should be able to implement this properly through the Launch Services API, but I can't quite figure out how to do it (I might be overlooking the obvious though).

// Extension method on NSWorkspace
@implementation NSWorkspace (MyExtraMethods)
- (BOOL) isPackageExtension: (NSString*) extension
{
    NSString * pathToTemp = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"Untitled" stringByAppendingPathExtension: extension]];
    [[NSFileManager defaultManager] createDirectoryAtPath:pathToTemp withIntermediateDirectories:NO attributes:nil error:NULL];
    BOOL result = [[NSWorkspace sharedWorkspace] isFilePackageAtPath: pathToTemp];
    [[NSFileManager defaultManager] removeItemAtPath:pathToTemp error:NULL];
    return result;
}
@end

// Basic test for the above
- (void) testIsPackageExtension
{
    STAssertFalse([[NSWorkspace sharedWorkspace] isPackageExtension: @"txt"], @"");
    STAssertFalse([[NSWorkspace sharedWorkspace] isPackageExtension: @"rtf"], @"");

    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"rtfd"], @"");
    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"app"], @"");
    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"kext"], @"");
    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"clr"], @"");

    /* The following tests depend on having applications installed
       that are not included in Mac OS X:
        .esproj   Espresso, tested with version 2.0.5 ( http://macrabbit.com/espresso/ )
        .dtps     Instruments, included in Xcode, tested with version 4.5 (4523) */
    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"esproj"], @"");
    STAssertTrue([[NSWorkspace sharedWorkspace] isPackageExtension: @"dtps"], @"");
}

Edit: The test above has been edited to include additional example extensions (original post only used "rtf" and "rtfd").

解决方案

You can query the Uniform Type Identifier information for your extension.
You first have to find out the correct UTI and then test if it conforms to com.apple.package (which is declared as kUTTypePackage):

- (BOOL)isPackageTypeForExtension:(NSString*)extension
{
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)(extension), NULL);
    return UTTypeConformsTo(UTI, kUTTypePackage);
}

Update:
Additionally you could check against kUTTypeBundle:

 UTTypeConformsTo(UTI, kUTTypeBundle)

and OR (|) the result into the return value of above method.

The following Apple docs describe how to define the UTI for a document based app (which often use NSFileWrappers & document bundles): https://developer.apple.com/library/mac/documentation/DataManagement/Conceptual/DocBasedAppProgrammingGuideForOSX/ApplicationCreationProcess/ApplicationCreationProcess.html#//apple_ref/doc/uid/TP40011179-CH6-997699

Update2:
Additionally to the UTI conforming to kUTTypePackage or kUTTypeBundle, there is a Package Bit file attribute, which can also mark a folder as package:

From the Apple's documentation:

How the System Identifies Bundles and Packages The Finder considers a directory to be a package if any of the following conditions are true:

  • The directory has a known filename extension: .app, .bundle, .framework, .plugin, .kext, and so on.
  • The directory has an extension that some other application claims represents a package type; see "Document Packages."
  • The directory has its package bit set.

Update3:
The UTI-based approach described above, does not cover all the cases the Finder takes into account when testing if a folder is a package or bundle.
It can be used to test if a specific UTI conforms to kUTTypeBundle or kUTTypePackage though.

这篇关于如何检查具有给定扩展名的目录是否显示为Finder作为包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆