Search code examples
cocoaswiftquicklook

How does e.g. TextWrangler generates the preview in finder?


i am almost done with my application. The user is able to edit special files. Now i want to provide a Finder preview but i get stuck.

I watched the apple video about Quick Lock but i am confused.

TextWrangler for example has a scrolable view of the file content. That is what i want for my Documents.

Can you give me a hint how to do this? enter image description here

My knowledge so far is that i have to write a QuickLock Plugin. The XCode template is wirtten in c, so i suggest i have to use c, not swift. If I am right two questions: - How do i get a scrolled view with text content form a file - How to put the .qlgenerator inside my main project's Contents/Library/.. folder?

Thanks a lot for any help. Two days reading is not always the way to get clear about things.

*** Update ** this is my info.plist CFBundleDocumentTypes

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeExtensions</key>
        <array>
            <string>json</string>
        </array>
        <key>CFBundleTypeIconFile</key>
        <string>Icon_512x512@2x</string>
        <key>CFBundleTypeName</key>
        <string>JSON Document</string>
        <key>CFBundleTypeOSTypes</key>
        <array>
            <string>TEXT</string>
        </array>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.json</string>
            <string>public.text</string>
            <string>public.data</string>
            <string>public.item</string>
            <string>public.content</string>
        </array>
        <key>NSDocumentClass</key>
        <string>$(PRODUCT_MODULE_NAME).Document</string>
    </dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.json</string>
        </array>
        <key>UTTypeDescription</key>
        <string>JSON source file</string>
        <key>UTTypeIconFile</key>
        <string>Icon_512x512@2x</string>
        <key>UTTypeIdentifier</key>
        <string>public.json</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.filename-extension</key>
            <array>
                <string>json</string>
            </array>
        </dict>
    </dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
        <array>
            <string>public.json</string>
        </array>
        <key>UTTypeDescription</key>
        <string>JSON source file</string>
        <key>UTTypeIconFile</key>
        <string>Icon_512x512@2x</string>
        <key>UTTypeIdentifier</key>
        <string>public.json</string>
        <key>UTTypeTagSpecification</key>
        <dict>
            <key>public.filename-extension</key>
            <array>
                <string>json</string>
            </array>
        </dict>
    </dict>
</array>

But this is still the preview without preview text or even an icon: enter image description here


Solution

  • It appears that your app just works with JSON files. That is, they are not some specialization of JSON files.

    Therefore, you should not attempt to export any UTI. You are using a system-defined UTI, and you should not export those. You just import them. (Exporting a UTI means that you are attempting to define the UTI. It's not about what types of files your app can write/save.)

    Then, in your LSItemContentTypes array, just list public.json. Your app can't open arbitrary text, data, or content. It can only open JSON data. So, just list that.

    Unfortunately, public.json conforms to public.text and not public.plain-text and it seems the system doesn't provide a QuickLook preview for that. So, you don't get for free with your documents.

    What you could do is export a new UTI which conforms to both public.json and public.plain-text. Your new UTI should use a different file extension to distinguish it from the system-defined public.json's extension. Then, add a dictionary to CFBundleDocumentTypes with the specifics for your unique document type. That way, your app will still be able to import .json files as well as your custom document type. I would expect that only your custom type would get QuickLook previews.

    For example, you'd put this in the UTExportedTypeDeclarations array:

        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.json</string>
                <string>public.plain-text</string>
            </array>
            <key>UTTypeDescription</key>
            <string>Your Document Type Description</string>
            <key>UTTypeIconFile</key>
            <string>Icon_512x512@2x</string>
            <key>UTTypeIdentifier</key>
            <string>com.yourcompany.yourapp.yourdocumenttypename</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>yourdocumentextension</string>
                </array>
            </dict>
        </dict>
    

    You'll have to fill in various placeholders that I put in there, since I don't know what good values would be. You would invent a filename extension that makes sense for your app. Likewise, you would invent a UTI based on the reverse domain name of your company, similar to your bundle identifier.

    Then, you would add this to the CFBundleDocumentTypes array as the first element:

        <dict>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>yourdocumentextension</string>
            </array>
            <key>CFBundleTypeIconFile</key>
            <string>Icon_512x512@2x</string>
            <key>CFBundleTypeName</key>
            <string>Your Document Type Description</string>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.yourcompany.yourapp.yourdocumenttypename</string>
            </array>
            <key>NSDocumentClass</key>
            <string>$(PRODUCT_MODULE_NAME).Document</string>
        </dict>
    

    Obviously, you'll need to fill in the placeholders again.