Search code examples
macoscocoafile-managementfileinfo

File type as seen in file's Get Info


I want to get the kind of a file at a certain path -- the same wording that you get from the file's Get Info window.

Then I can know whether it is a document, script, binary, or a folder. How can I do this?

NSString *path = [@"/Downloads/test.txt"];
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&attributesError];

Solution

  • You can get the document kind as shown in the Finder using code like this:

    NSURL* url = [NSURL fileURLWithPath:path];
    NSString* documentKind;
    NSError* error;
    if ([url getResourceValue:&documentKind forKey:NSURLLocalizedTypeDescriptionKey error:&error])
    {
        // use documentKind here
    }
    else
    {
        /* handle error */
    }
    

    However, the document kind is not suitable for making programmatic decisions. First, as should be clear, it is localized. That means it may change based on the system language. It can also change with different releases of the OS (for system-defined document kinds) or applications (for application-defined kinds).

    If you want to make programmatic decisions about files, you should use the Uniform Type Identifier. To obtain that, you can use code similar to the above, except use the NSURLTypeIdentifierKey key. You could also use -[NSWorkspace typeOfFile:error:] to get that type given a path.

    To compare UTIs, you should generally not use string equality. Instead, you should use -[NSWorkspace type:conformsToType:] to find if a file's UTI conforms to one that you are interested in handling in some specific way. That way, if the file's type is a more-specific variant of the one you handle, you'll still handle it that way. For example, if you handle public.plain-text in a particular way and you encounter a file of type public.objective-c-source, you'll still handle it because it is-a plain text file.