Adding custom document icon for document based Mac OS 16 App

Starting with Mac OS 16, Document Icons can be generated by defining a background and a Foreground element (see Apple Documentation).

I've defined the mentioned elements in my Assets and in the info.plist. Unfortunately I still can't see my custom icons. Neither on existing files, nor on newly saved files. I even added a Legacy Icon - which is also not shown in Mac OS.

The full source code of the app is over at gitHub .

Would be great if someone could point out what I'm not seeing here.

Thanks a lot, Holger

Here the relevant part of the info.plist

	<array>
		<dict>
			<key>CFBundleTypeIconFile</key>
			<string>Legacy</string>
			<key>CFBundleTypeIconSystemGenerated</key>
			<integer>1</integer>
			<key>CFBundleTypeName</key>
			<string>StateTransfer Request</string>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>LSHandlerRank</key>
			<string>Default</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>de.holgerkrupp.statetransfer.request</string>
			</array>
			<key>NSDocumentClass</key>
			<string>NSDocument</string>
		</dict>
	</array>

	<key>UTExportedTypeDeclarations</key>
	<array>
		<dict>
			<key>UTTypeConformsTo</key>
			<array/>
			<key>UTTypeDescription</key>
			<string>StateTransfer Request</string>
			<key>UTTypeIconFile</key>
			<string>Legacy</string>
			<key>UTTypeIcons</key>
			<dict>
				<key>UTTypeIconBackgroundName</key>
				<string>IconBackground</string>
				<key>UTTypeIconBadgeName</key>
				<string>IconForeground</string>
				<key>UTTypeIconText</key>
				<string>REST</string>
			</dict>
			<key>UTTypeIdentifier</key>
			<string>de.holgerkrupp.statetransfer.request</string>
			<key>UTTypeTagSpecification</key>
			<dict>
				<key>public.filename-extension</key>
				<array>
					<string>httprequest</string>
				</array>
				<key>public.mime-type</key>
				<array>
					<string>application/json</string>
				</array>
			</dict>
		</dict>
	</array>
	<key>UTImportedTypeDeclarations</key>
	<array>
		<dict>
			<key>UTTypeConformsTo</key>
			<array/>
			<key>UTTypeDescription</key>
			<string>StateTransfer Request</string>
			<key>UTTypeIconFile</key>
			<string>Legacy</string>
			<key>UTTypeIcons</key>
			<dict>
				<key>UTTypeIconBackgroundName</key>
				<string>IconBackground</string>
				<key>UTTypeIconBadgeName</key>
				<string>IconForeground</string>
				<key>UTTypeIconText</key>
				<string>REST</string>
			</dict>
			<key>UTTypeIdentifier</key>
			<string>de.holgerkrupp.statetransfer.request</string>
			<key>UTTypeTagSpecification</key>
			<dict>
				<key>public.filename-extension</key>
				<array>
					<string>httprequest</string>
				</array>
				<key>public.mime-type</key>
				<array>
					<string>application/json</string>
				</array>
			</dict>
		</dict>
	</array>
Answered by DTS Engineer in 827925022

Your Info.plist doesn't look quite right to me. For example, I see the following in your Info.plist:

    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array/>

Here, to export a document type you own, you will need to declare the UTI it conforms to in the UTTypeConformsTo entry, rather than using an empty array.

I'd suggest that you start with the simple case, make sure it works, and then incrementally add the complexity from there.

I confirm that UTTypeIcons works with the following steps:

a. Use Xcode to create a Multiplatform Document App. For convenience, let's name it MyDocumentIconsTest. I use Xcode 16.2 (16C5032a) + macOS 15.3.1 (24D70), btw.

b. Run it on my Mac, and confirm that the template app can create and save a document correctly. At this point, without me changing anything, the document UTI is com.example.plain-text, the file extension is exampletext, and the document icon is all white.

c. Copy the IconBackground asset from your project, and paste it to the asset catalog (Assets) of MyDocumentIconsTest. This makes the icon asset available in MyDocumentIconsTest.

d. In Xcode's Project Navigator, select the project, then go to General > Identity > build, and increase the build number. This makes sure that the system updates the document type information next time I build and run the app.

e. Replace the template content of the Info.plist with the following text, which adds a UTExportedTypeDeclarations section:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>com.example.plain-text</string>
			</array>
			<key>NSUbiquitousDocumentUserActivityType</key>
			<string>$(PRODUCT_BUNDLE_IDENTIFIER).exampledocument</string>
		</dict>
	</array>
	<key>UTImportedTypeDeclarations</key>
	<array>
		<dict>
			<key>UTTypeConformsTo</key>
			<array>
				<string>public.plain-text</string>
			</array>
			<key>UTTypeDescription</key>
			<string>Example Text</string>
			<key>UTTypeIdentifier</key>
			<string>com.example.plain-text</string>
			<key>UTTypeTagSpecification</key>
			<dict>
				<key>public.filename-extension</key>
				<array>
					<string>exampletext</string>
				</array>
			</dict>
		</dict>
	</array>
    
    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.plain-text</string>
            </array>

            <key>UTTypeDescription</key>
            <string>Example Text</string>
            <key>UTTypeIcons</key>
            <dict>
                <key>UTTypeIconBackgroundName</key>
                <string>IconBackground</string>
                <key>UTTypeIconText</key>
                <string>REST</string>
            </dict>
            <key>UTTypeIdentifier</key>
            <string>com.example.plain-text</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>exampletext</string>
                </array>
            </dict>
        </dict>
    </array>

</dict>
</plist>

f. Run the app again, and try to create and save a new document.

At this point, I see that the background (IconBackground) and text ("REST") specified with UTTypeIconBackgroundName and UTTypeIconText show up in the document icon.

I'd suggest that you try the above steps as well to see if you get the same result. If yes, you can then use the project as the base line for your development.

macOS caches the information related to document types, and the cache isn't updated every time you build and run your app. If you see that your changes on the Info.plist doesn't present immediately, try to increase the build number, as mentioned in step d, and if that doesn't work, try with a clean macOS system.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Here a minimal project reproducing the https://github.com/holgerkrupp/TEST-DocumentIcons

Your Info.plist doesn't look quite right to me. For example, I see the following in your Info.plist:

    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array/>

Here, to export a document type you own, you will need to declare the UTI it conforms to in the UTTypeConformsTo entry, rather than using an empty array.

I'd suggest that you start with the simple case, make sure it works, and then incrementally add the complexity from there.

I confirm that UTTypeIcons works with the following steps:

a. Use Xcode to create a Multiplatform Document App. For convenience, let's name it MyDocumentIconsTest. I use Xcode 16.2 (16C5032a) + macOS 15.3.1 (24D70), btw.

b. Run it on my Mac, and confirm that the template app can create and save a document correctly. At this point, without me changing anything, the document UTI is com.example.plain-text, the file extension is exampletext, and the document icon is all white.

c. Copy the IconBackground asset from your project, and paste it to the asset catalog (Assets) of MyDocumentIconsTest. This makes the icon asset available in MyDocumentIconsTest.

d. In Xcode's Project Navigator, select the project, then go to General > Identity > build, and increase the build number. This makes sure that the system updates the document type information next time I build and run the app.

e. Replace the template content of the Info.plist with the following text, which adds a UTExportedTypeDeclarations section:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDocumentTypes</key>
	<array>
		<dict>
			<key>CFBundleTypeRole</key>
			<string>Editor</string>
			<key>LSItemContentTypes</key>
			<array>
				<string>com.example.plain-text</string>
			</array>
			<key>NSUbiquitousDocumentUserActivityType</key>
			<string>$(PRODUCT_BUNDLE_IDENTIFIER).exampledocument</string>
		</dict>
	</array>
	<key>UTImportedTypeDeclarations</key>
	<array>
		<dict>
			<key>UTTypeConformsTo</key>
			<array>
				<string>public.plain-text</string>
			</array>
			<key>UTTypeDescription</key>
			<string>Example Text</string>
			<key>UTTypeIdentifier</key>
			<string>com.example.plain-text</string>
			<key>UTTypeTagSpecification</key>
			<dict>
				<key>public.filename-extension</key>
				<array>
					<string>exampletext</string>
				</array>
			</dict>
		</dict>
	</array>
    
    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.plain-text</string>
            </array>

            <key>UTTypeDescription</key>
            <string>Example Text</string>
            <key>UTTypeIcons</key>
            <dict>
                <key>UTTypeIconBackgroundName</key>
                <string>IconBackground</string>
                <key>UTTypeIconText</key>
                <string>REST</string>
            </dict>
            <key>UTTypeIdentifier</key>
            <string>com.example.plain-text</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>exampletext</string>
                </array>
            </dict>
        </dict>
    </array>

</dict>
</plist>

f. Run the app again, and try to create and save a new document.

At this point, I see that the background (IconBackground) and text ("REST") specified with UTTypeIconBackgroundName and UTTypeIconText show up in the document icon.

I'd suggest that you try the above steps as well to see if you get the same result. If yes, you can then use the project as the base line for your development.

macOS caches the information related to document types, and the cache isn't updated every time you build and run your app. If you see that your changes on the Info.plist doesn't present immediately, try to increase the build number, as mentioned in step d, and if that doesn't work, try with a clean macOS system.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Adding custom document icon for document based Mac OS 16 App
 
 
Q