Safari - Clear cache and cookies on quit

Hi folks,

NOTE: This is now a free drag and drop application that that provides options to clear cache, cookies, history etc each time Safari quits. No need for users to deal with code or scripts. Ive posted it at sourceforge. Feel free to download and enjoy!
https://sourceforge.net/projects/safaricleaner/

ORIGINAL POST BELOW:

It drives me nuts that Safari doesnt let you clear cache and cookies on quit, so I wrote a little script to do that. It also clears “local storage”, history, top sites, and has an option to turn Private Browsing on automatically on launch if you want that. Im posting it mostly to share, and any improvements would be great. Im on 10.7.3 using Safari 5.1.3. You can adjust what actions are taken or not taken easily by commenting or uncommenting try blocks in the “clear_all” handler.

The way it works is you’ll have a launch agent watching the Safari preference for changes (which happens every time Safari is launched). If Safari is launched and the Applescript isn’t running yet, the applescript will launch and run alongside Safari. When you quit either Safari or Safari_Helper, both apps quit, and all cookies, cache and local storage are cleared.

To create the launch agent, use your favorite text editor (don’t use applescript editor. I use TextWrangler, its free and great) and save the following code as a text file named “com.safarihelper.launchd.plist” . Place the file in ~/Library/LaunchAgents. Please note that you must replace with your actual user name in the 4th to last line:


<?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>Disabled</key>
	<false/>
	<key>Label</key>
	<string>com.safarihelper.launchd</string>
	<key>OnDemand</key>
	<true/>
	<key>ProgramArguments</key>
	<array>
		<string>/bin/bash</string>
		<string>-c</string>
		<string>if ! ps aux | grep '/Applications/Safari_Helper.app'| grep -v grep && ps aux | grep '/Applications/Safari.app'| grep -v grep; then nohup /Applications/Safari_Helper.app/Contents/MacOS/applet; exit; fi</string>
	</array>
	<key>RunAtLoad</key>
	<false/>
	<key>WatchPaths</key>
	<array>
		<string>/Users/<YOURUSERNAME>/Library/Preferences/com.apple.Safari.plist</string>
	</array>
</dict>
</plist>

The file should have 644 permissions and be owned by your user with group staff (which is default normally). If your file has different permissions and you’re not familiar with how to set it, run the following commands in Terminal:

sudo chmod 644 ~/Library/LaunchAgents/com.safarihelper.launchd.plist
sudo chown :staff ~/Library/LaunchAgents/com.safarihelper.launchd.plist

Now for the applescript: Save the following code as a stay open application named Safari_Helper and place it in the Applications folder. Thats all there is to it. Enjoy!



tell application "Safari" to activate

--if you want private browsing automatically enabled, set "Private Browsing" command to cmd+opt+p in Keyboard system preferences, check "Enable access for assistive device" in the "Universal Access" system preference, then uncomment the next two lines. 

--delay 1
--tell application "System Events" to keystroke "p" using {command down, option down}

on quit
	if isRunning("Safari") is true then
		tell application "Safari" to quit
	end if
	clear_all()
	continue quit
end quit

on idle
	if isRunning("Safari") is false then
		quit
	end if
	return 5
end idle

on isRunning(appName)
	tell application "System Events" to (name of processes) contains "Safari"
end isRunning

on clear_all()
	set myName to do shell script "whoami"
	
	try
		do shell script "launchctl unload /System/Library/LaunchAgents/com.apple.cookied.plist"
	end try
	
	try
		do shell script "rm /Users/" & myName & "/Library/Cookies/Cookies.binarycookies"
	end try
	
	try
		do shell script "launchctl load /System/Library/LaunchAgents/com.apple.cookied.plist"
	end try
	
	try
		do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/Support/cookied"
	end try
	
	try
		do shell script "rm /Users/" & myName & "/Library/Caches/com.apple.Safari/Cache.db"
	end try

	try
		do shell script "rm /Users/" & myName & "/Library/Safari/History.plist"
	end try
	
	try
		do shell script "rm /Users/" & myName & "/Library/Safari/TopSites.plist"
	end try
	
	try
		do shell script "rm /Users/" & myName & "/Library/Safari/LocalStorage/*"
	end try
end clear_all


Hi,

the launchctl lines will never be passed error-free because launchd agents/daemons in the system domain require root privileges. Without sudo (aka with adminstrator privileges) it considers only agents/daemons in the user domain

Hi Stefan,

Thanks for the attempt to help. It does seem like it should require root privileges, but It actually doesn’t, as evidenced by the following series of commands where I unload the cookie daemon on the command line as my user (an admin, but not root). Ive tested thoroughly, and the steps in the applescript execute without error.

$ launchctl list | grep cookie
2012 - com.apple.cookied
$ launchctl unload /System/Library/LaunchAgents/com.apple.cookied.plist
$ launchctl list | grep cookie
$
$

Hello

This piece of the code generate an error (filtered of course)


 try
       do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/Support/cookied"
   end try

→ error “La commande s’est arrêtée avec un état non nul.” number 255

Yvan KOENIG (VALLAURIS, France) mercredi 7 mars 2012 09:58:29

Awesome. Its not every day I get to see my errors in french! Yes, this line does generate error 255 (filtered, of course). Fortunately that line in the applescript is extraneous. I put it there just to try to get the cookied process to start back up after reloading the launchdaemon. Its basically irrelevant though, since the launchdaemon gets loaded without issue and it spawns the cookied process automatically on next launch of Safari. Still, if anyone knows a way to kickstart the cookied process without launching Safari, please let me know and Ill add it in there.

Hi.

I have the same OS and Safari version and I wanted to comment on the Private browsing option that if you have say 1Password it is unable to find the database. Commenting out the Private Browsing resolves this issue if one should have that enabled.

Things I have noticed.

  1. I love this script and I have done as you have instructed in the quoted text above along with the dock removal and the script naming and icon replacement.

  2. It seems to me after several uses that is you do not have the script running, say you quite Safari and happen along a link in say mail and click it the blue dot under the script in the dock is not there indicating the script is not running and Safari is running without the benefit of the script.

If I am right, is there something in the script that should be uncommented so links ect, open using the script or did I do a step wrong in the creation of the script?

Thank you for this excellent piece of work.

Sincerely,

Leon Sargent

Model: Mid 2010 Mini Server
AppleScript: 2.2.1
Browser: Safari 534.53.10
Operating System: Mac OS X (10.7)

Glad to hear you’re making use of the script! I hadn’t originally planned for contingencies like opening links from mail.app, but your post inspired me to rework it to be a better system. I wrote a launch agent that will watch the safari preference for changes and launch the script if its not open already. This makes it so you don’t need the helper applescript in the dock, it will just launch on its own whenever Safari is launched (including when links are clicked in Mail.app). Nice and easy. Ive replaced the original instructions in the top post to reflect the new method.

This is a known issue with 1password and Safari’s private browsing (nothing to do with this script). Agile bits says Apple is aware of the bug within Safari and is planning to (one day) fix it.