How can I remove Dock item in Yosemite?

For reference, if anybody else needs to remove items from their Dock, this seems to work:

use framework "Foundation"
use scripting additions

set prefsFile to (POSIX path of (path to preferences from user domain)) & "com.apple.dock.plist"
set removeApps to {"TextEdit"}
set dockRec to my readPlistAt:prefsFile
set appRecords to |persistent-apps| of dockRec
set newAppRecord to {}
repeat with anAppRecord in appRecords
	if |file-label| of |tile-data| of anAppRecord is not in removeApps then copy contents of anAppRecord to end of newAppRecord
end repeat
set |persistent-apps| of dockRec to newAppRecord
my saveRecord:dockRec toPlistAt:prefsFile
repeat 2 times
	do shell script "killall Dock"
	delay 3
end repeat

on saveRecord:theRecord toPlistAt:posixPath
	set theDict to current application's NSDictionary's dictionaryWithDictionary:theRecord
	set thePath to current application's NSString's stringWithString:posixPath
	set thePath to thePath's stringByExpandingTildeInPath()
	theDict's writeToFile:thePath atomically:true
end saveRecord:toPlistAt:

on readPlistAt:posixPath
	set thePath to current application's NSString's stringWithString:posixPath
	set thePath to thePath's stringByExpandingTildeInPath()
	set theDict to current application's NSDictionary's dictionaryWithContentsOfFile:thePath
	return theDict as record
end readPlistAt:

Note, it’s unclear to me why I need to restart the Dock twice with a delay in between, but so far it’s working reliably on several tests with this. I tried different numbers of repeats and different delays… I wasn’t exhaustive about it, but the 2 repeats with a 3 second delay in between seems to be reliable on my machine. Your mileage may vary.

I don’t remember exactly from whom I got the following script. It is designed to remove the application icon in the Dock and is more compact.


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

removeDockItem("VLC")

on removeDockItem(dockItemName)
	set dockDefaults to current application's class "NSUserDefaults"'s alloc()'s initWithSuiteName:"com.apple.dock"
	set apps to dockDefaults's objectForKey:"persistent-apps"
	if (apps's |count|() > 0) then
		set filter to current application's class "NSPredicate"'s predicateWithFormat:("%K != %@") argumentArray:({"tile-data.file-label", dockItemName})
		set appsCopy to apps's filteredArrayUsingPredicate:(filter)
		if (appsCopy's |count|() < apps's |count|()) then
			tell dockDefaults to setObject:(appsCopy) forKey:("persistent-apps")
			tell application "Dock" to quit -- Possibly a bit extreme.
		end if
	end if
end removeDockItem

Thanks! I’ll give that a shot.

Interestingly, the “tell dockDefaults to setObject:(appsCopy) forKey:(“persistent-apps”)” seems to make it so that a single “tell application “Dock” to quit” is sufficient.

I didn’t experiment with this much; I did use the “tell…quit” statement in your script, and maybe the difference was that vs. the “shell…killall” statement. Not important for me to get to the bottom of, this is working better.

I kept the less succinct Applescript Repeat Loop just because I’m familiar with it and can edit it as needed… I’m thinking I might want to use this script to re-arrange the dock to. The idea here is that when a user changes an entire branch of our code to test, the internal references in all our apps are consistent within whatever branch they move to, but if they added an application to the dock, then it’s got a hard-coded path pointing to something on the wrong branch… which can cause trouble.

So I want the script that switches their branch to also find and remove any apps pointing to apps on the old branch, and then add the equivalent script from the new branch.

But if I just run the handler as I have it, and then run a standard shell line to add the correct copy using (do shell script "defaults write …) then it’s going to re-arrange their dock.

So maybe I’ll also have this re-arrange it back for them. I’ll probably wait and see if there are any complaints.

Thanks again, Shane and KniazidisR! Great stuff, super helpful.

In case it’s useful to someone, here’s more complete code that keeps track of which apps were in the dock, and will only add back ones it actually removed.


use framework "Foundation"
use scripting additions


set checkApps to {"TextEdit","Mail","Whatever App Name," "Etc."}
set removedApps to remove_apps_from_dock(checkApps)
tell script "My Additions" to set scriptsFolder to POSIX path of get_scripts_folder()
set missingApps to {}
set appPaths to {}
repeat with anApp in removedApps
	try
		set thisAppPath to scriptsFolder & anApp & ".app"
		set thisAlias to (thisAppPath as POSIX file) as alias
		set appPaths to appPaths & thisAppPath
	on error
		set missingApps to missingApps & anApp
	end try
end repeat
if (count of missingApps) > 0 then
	set missinglist to ""
	repeat with anApp in missingApps
		set missinglist to return & anApp & missinglist
	end repeat
	display dialog "The following applications were in your dock, but don't exist on the new branch. The old copies will be removed from your dock and not replaced." & missinglist
end if
if (count of removedApps) > 0 then
	repeat with anAppPath in appPaths
		add_app_to_dock(anAppPath)
	end repeat
	tell application "Dock" to quit
end if

on remove_apps_from_dock(removeApps)
	set dockDefaults to current application's class "NSUserDefaults"'s alloc()'s initWithSuiteName:"com.apple.dock"
	set appRecord to dockDefaults's objectForKey:"persistent-apps"
	set newAppRecord to {}
	set removedApps to {}
	repeat with anAppRecord in appRecord
		set appName to (|file-label| of |tile-data| of anAppRecord) as text
		if appName is in removeApps then
			set removedApps to removedApps & appName
		else
			copy contents of anAppRecord to end of newAppRecord
		end if
	end repeat
	tell dockDefaults to setObject:(newAppRecord) forKey:("persistent-apps")
	return removedApps
end remove_apps_from_dock

on add_app_to_dock(appPath)
	if class of appPath is alias then set appPath to POSIX path of appPath
	do shell script "defaults write com.apple.dock persistent-apps -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>" & appPath & "</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>'"
end add_app_to_dock

It calls a “get_scripts_folder()” handler from a library that I’m not including, because it would be localized to an individual’s setup. Replace as appropriate for wherever your apps are.