Question

I'm trying to get the file extension using [string pathExtension] but this does not always return the file extension per se. Eg: I have a file named 'Example.png', when I use this method I get 'png' which is correct. Now let's say I have a file with no extension, like 'Example', I get nil which is still correct. What happens when I have a file like 'Example.109'? I get '109' as the extension which is incorrect. It so happens that '.109' is part of the filename itself. Is there a way to validate this?

Was it helpful?

Solution

I take your meaning of valid filename extension to be a filename extension for which there is an application present on the system that claims/declares that extension.

You can easily determine that by using the following code:

NSString *pathExtension = [@"Example.109" pathExtension];

NSLog(@"pathExtension == %@", pathExtension);

CFStringRef utiType = UTTypeCreatePreferredIdentifierForTag(
       kUTTagClassFilenameExtension, (__bridge CFStringRef)pathExtension, NULL);

NSLog(@"utiType == %@", utiType);

CFDictionaryRef declaration = UTTypeCopyDeclaration(utiType);

NSLog(@"declaration == %@", declaration); // will likely print (null)


CFStringRef jpgUTIType = UTTypeCreatePreferredIdentifierForTag(
         kUTTagClassFilenameExtension, CFSTR("jpg"), NULL);

NSLog(@"jpg's UTI Type == %@", jpgUTIType);

CFDictionaryRef knownDeclaration = UTTypeCopyDeclaration(jpgUTIType);

NSLog(@"knownDeclaration == %@", knownDeclaration);

if (utiType) CFRelease(utiType);
if (knownFilenameExtensionsUTIType) CFRelease(knownFilenameExtensionsUTIType);
if (declaration) CFRelease(declaration);
if (knownDeclaration) CFRelease(knownDeclaration);

That will likely print the following to console:

pathExtension == 109
utiType == dyn.age8xcqb3
declaration == (null)

jpg's UTI Type == public.jpeg
knownDeclaration == {
    UTTypeConformsTo = "public.image";
    UTTypeDescription = "JPEG image";
    UTTypeIdentifier = "public.jpeg";
    UTTypeTagSpecification =     {
        "com.apple.ostype" = JPEG;
        "public.filename-extension" =         (
            jpeg,
            jpg,
            jpe
        );
        "public.mime-type" =         (
            "image/jpeg",
            "image/jpg"
        );
    };
}

As you can see from the printed results, the call to UTTypeCopyDeclaration() for the UTI type associated with the .109 filename extension returned NULL, which means there is no application that declares that filename extension. Compare that to the results returned for the UTTypeCopyDeclaration() call with the UTI type associated with the .jpg filename extension. There, the call returns a valid dictionary that contains the information, since there is an application (or the system itself) declares that filename extension.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top