Search code examples
xcodemacosiconsfinderuti

How can I turn off Finder's icon preview for my app's document type?


I have managed to do the proper dance and get a custom UTI set up for my OS X app's document type, with a custom file extension and so forth. I set up an icon for my file type as well, and that is also working. I know this because when I save a new file from my app, I can see it appear in the Finder with the correct icon. BUT – about a second later, the Finder replaces my icon with one of its generic "preview" icons, showing the text contents of my file inside the icon, with my file extension, capitalized, at the bottom of the preview icon, like this:

enter image description here

I think this is happening because I declare my custom UTI as having MIME type text/plain and conforming to public.utf8-plain-text. I do want to do that, because they are in fact text files, and I want to allow the user to treat them as such, other apps to recognize them as such, etc. But given this, the Finder (perhaps through some QuickLook generator or something) therefore says "aha, it's a text file, I know how to make custom preview icons for text files!" and replaces my custom icon. Which, needless to say, is not what I want. How can I prevent this from happening? I'm using Objective-C in my project, but I don't think this is a language-specific issue; it all has to do with the UTI declarations in my app's plist.

Speaking of which, here's a screenshot of the way my UTI is configured in Xcode:

enter image description here

And here's a screenshot of the UTI export in Xcode:

enter image description here

It is fine that the icon previews there show as question marks; that is because the icon images are included in my project as a .iconset folder that is turned into the requisite .icns file by Xcode at build time, and Xcode isn't smart enough to show the right preview. But as I said above, the correct icon does display for a second in the Finder, before it gets replaced by the preview icon, so the setup of the icon .icns file and the binding of the .icns to the UTI is clearly working. Along the same lines, if I do a "Get Info" on my file in the Finder, by the way, it shows the correct icon there in the upper left of the information window. The correct icon is also shown in the title bar of the window in my app. It is just in the Finder's display that the wrong icon is used. Any ideas?


Solution

  • As mentioned by others, modern macOS versions generate thumbnails for public.text too and so @bhaller's solution no longer works.

    As of macOS 15, there seem to be only two options:

    1. The user-hostile one: don't declare conformity to public.text. This sucks because the file can no longer be easily opened in TextEdit etc., but it works.

    2. The ugly hack: implement a Thumbnail Extension for the app, with a QLThumbnailProvider implementation the entire purpose of which will be to fail to create a thumbnail:

    
    @interface ThumbnailProvider : QLThumbnailProvider
    @end
    
    @implementation ThumbnailProvider
    
    - (void)provideThumbnailForFileRequest:(QLFileThumbnailRequest *)request
                         completionHandler:(void (^)(QLThumbnailReply * _Nullable, NSError * _Nullable))handler
    {
        handler([QLThumbnailReply replyWithContextSize:request.maximumSize
                            currentContextDrawingBlock:^BOOL {
            // return YES if the thumbnail was successfully drawn inside this block
            return NO;
        }], nil);
    }
    
    @end
    

    Finder will then known to use this appex to create the thumbnail and won't fallback to the default implementation even if thumbnail creation fails.