Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Code samples for an AppleScript preferences system Apps
I have been frustrated for some time by the inability to add preferences to simple AppleScript apps. So I wrote my own system for creating and reading preferences. The following are the snippets for doing different things.

[robg adds: I have not tested these snippets, as I don't have very strong AppleScript skills. But if you're looking for a way to add a basic preference system to your code, these would seem to be a good starting point...]

The code is free. Re-use at will, but please leave this acknowledgement in your code. Feel free to email me and tell me you've found it helpful!

Base for Prefs:
(*
Preference system version 1

Chris J. Shull
themacgeek@comcast.net
http://home.comcast.net/~themacgeek/

The code is free. Re-use at will, but please leave this acknowledgement in your code.
Feel free to email me and tell me you've found it helpful!
*)

---Base prefs snippet
set prefname to "com.ShullianProductions.preftester" --this will be the filename
set prefcontent to "para 1" & return & "para 2" --this will be the content of the pref file. NOTE that you can create multiple lines
set prefpath to FindPrefFolder() --finds the path to the user's Prefs folder
set ContentParaNumber to 1 --is the paragragh that will be found in a single preference finder. change it throughout the script to switch paragragh found
---End of Base


Writing prefs:
--write prefs snippet (overrides original)
if CheckIfExists(prefname, prefpath) is true then DeleteAFile(prefname, prefpath)
MakeAFile(prefname, prefcontent, prefpath)
--end write prefs


Reading Prefs:
---read Prefs snippet
if CheckIfExists(prefname, prefpath) then
	set pref to paragraph ContentParaNumber of ReadAFile(prefname, prefpath)
	set ThereArePrefs to true
else
	set ThereArePrefs to false
end if
if ThereArePrefs then display dialog pref --or whatever you want
---End read


Subroutines
---Subroutines-for-preferences-----------------
on UnixfyPath(stringer, origchar, newchar)
	set the testlist to the text items of the stringer
	repeat with letter in testlist
		set let to letter as string
		set orig to origchar as string
		if let is orig then
			set the contents of the letter to newchar
		end if
	end repeat
	set the newpath to "/Volumes/" & (the testlist as text)
	return the newpath
end UnixfyPath

on MakeAFile(filename, filecontents, folderpath)
	tell application "Finder"
		do shell script ("echo "" & filecontents & "" | cat > "" & folderpath & "/" & filename & """)
	end tell
end MakeAFile

on ReadAFile(filename, folderpath)
	tell application "Finder"
		set filecontent to do shell script "cat "" & folderpath & filename & """
	end tell
	return filecontent
end ReadAFile

on DeleteAFile(filename, folderpath)
	tell application "Finder"
		do shell script "rm "" & folderpath & filename & """
	end tell
end DeleteAFile

on CheckIfExists(filename, folderpath)
	tell application "Finder"
		set folder_cmd to ("find "" & folderpath & filename & """)
		try
			do shell script folder_cmd
			set worked to true
		on error
			set worked to false
		end try
	end tell
	return worked
end CheckIfExists

on FindPrefFolder()
	tell application "Finder" to set libpath to path to home folder
	set UnixPath to UnixfyPath("OS X HD:Users:chris:", ":", "/")
	set prefpath to UnixPath & "Library/Preferences/"
	return prefpath
end FindPrefFolder
--End-of-Subroutines-for-preferences-----------------
    •    
  • Currently 3.25 / 5
  You rated: 5 / 5 (4 votes cast)
 
[11,958 views]  

Code samples for an AppleScript preferences system | 13 comments | Create New Account
Click here to return to the 'Code samples for an AppleScript preferences system' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Code samples for an AppleScript preferences system
Authored by: roxeteer on Apr 06, '05 10:43:53AM
I think you're making it overly difficult... You can write a preference to a file in Terminal with
defaults write com.ShullianProductions.preftester 'prefName' 'prefValue'
You can read a named preference with
defaults read com.ShullianProductions.preftester 'prefName'
Then you can execute these commands in AppleScript with
do shell script "defaults write com.ShullianProductions.preftester 'prefName' 'prefValue'"


[ Reply to This | # ]
Code samples for an AppleScript preferences system
Authored by: aamann on Apr 06, '05 12:14:31PM
The defaults command requires the BSD subsystem to be installed or it will fail - for AppleScript Studio applciations you should use the AppleScript Version of theis command (which is part of the AppleScript.framework and thus always present):
default entry [of ...]
If you use of user defaults, there is no need to add a prefs name, it will automatically use the application's bundle identifier.
Here are some handlers I use for reading/writing prefs (the reading one allows you to set a default value in case the key is not present - if no value is present in the prefs file, a new key with the default value will be added. That way you are sure to always get something back...):

on readDefaultEntry(theKey, defaultValue)
  try
    set theResult to contents of default entry theKey of user defaults
  on error
    make new default entry at end of default entries of user defaults with properties {name:theKey, contents:defaultValue}
    set theResult to defaultValue
  end try
  return theResult
end readDefaultEntry

on writeDefaultEntry(theKey, theValue)
  set contents of default entry theKey of user defaults to theValue
end writeDefaultEntry


[ Reply to This | # ]
Do not use absolute path!
Authored by: cnotarianni on Apr 06, '05 11:15:19AM
why do you use absolute path?
on FindPrefFolder()
tell application "Finder" to set libpath to path to home folder
set UnixPath to UnixfyPath("OS X HD:Users:chris:", ":", "/")
set prefpath to UnixPath & "Library/Preferences/"
return prefpath end FindPrefFolder

Maybe use relative path... and POSIX path of to trasform path in posix path style

set UserHome to path to (home folder) as text
set UserLibrary to UserHome & "Library:"
set prefpath to UserHome & "Library:Preferences"
set UserName to name of folder UserHome

set PosixUserName to POSIX path of UserName
set prefpath to POSIX path of prefpath


[ Reply to This | # ]
Do not use absolute path!
Authored by: powerbookg3user0 on Apr 06, '05 12:25:53PM

No, just use "~/Library/Preferences"

---
Takumi Murayama



[ Reply to This | # ]
Do not use absolute path!
Authored by: tenthumbs on Apr 06, '05 12:36:26PM
set prefsPath to (path to preferences folder from user domain as text) & "my prefs"
set prefsPath to POSIX path of prefsPath


[ Reply to This | # ]
Do not use absolute path!
Authored by: tenthumbs on Apr 06, '05 12:42:36PM
actually ment to post this: set prefsPath to POSIX path of (path to preferences folder from user domain as text) & "my prefs"

[ Reply to This | # ]
Or...
Authored by: cnotarianni on Apr 06, '05 01:11:46PM
set prefsPath to (system attribute "HOME") & "/Library/Preferences/my prefs"

[ Reply to This | # ]
Or...
Authored by: tenthumbs on Apr 06, '05 01:35:29PM

i'm not sure it's called "Library" in all system languages, tho



[ Reply to This | # ]
Code samples for an AppleScript preferences system
Authored by: designr on Apr 06, '05 02:22:33PM

Maybe this is a silly question but, why can't you use the "Property" declaration to establish nonvolatile preferences?

Applescript stores and retains "Property" values between launches.

--First, declare properties (which like "Globals" can be called from within subroutines):

property my_file_list : {}
property my_pref_1_option_list : {
"list_item_1",
"list_item_2",
"list_item_3",
"list_item_4"}
property my_pref_1 : {}
property my_pref_2 : ""
property my_pref_3 : ""
property my_pref_4 : ""

--Then, create a steps to check if each pref is empty:

if my_file_list = {} then set_my_file_list()
if myPref_1 = {} then set_my_pref_1()
if myPref_2 = "" then set_my_pref_2()
if myPref_3 = "" then set_my_pref_3()
if myPref_4 = "" then set_my_pref_4()

--Then create a subroutine to set each pref (you can use other triggers to call these subroutines if you want to change the values):

on set_my_file_list ()
set my_file_list to choose file with multiple selections allowed
end set_my_file_list

on set_my_pref_1 ()
set my_pref_1 to choose from list my_pref_1_option_list with prompt "Choose:" with multiple selections allowed
end set_my_pref_1

on set_my_pref_2 ()
set my_pref_2 to display dialog "Type Whatever:" default answer "" buttons {"Skip","OK"} default button 2
end set_my_pref_2

--And so on....



[ Reply to This | # ]
Code samples for an AppleScript preferences system
Authored by: aamann on Apr 06, '05 02:30:37PM

This won't work since properties are not preserved between runs for AppleScript Studio applications.



[ Reply to This | # ]
reinventing the wheel
Authored by: xcgr on Apr 06, '05 02:36:51PM

Not a very good hint, IMO, for the reasons mentioned above. Either use AppleScript Studio's built-in routines, or glue together 'do shell script' and /usr/bin/defaults. Rolling your own makes no sense when Apple already gives you tools that do the same thing -- and probably do it better than your own code.



[ Reply to This | # ]
Re: reinventing the wheel
Authored by: Krioni on Apr 06, '05 06:01:27PM

The original hint was for _simple_ AppleScript apps, not for AppleScript Studio apps. In other words, he wrote a quick script in Script Editor and chose Save as Application.

I didn't review the handlers to see how good they looked, but he certainly can't use the 'user defaults' commands from a plain AppleScript app. I would use 'do shell script' with the 'defaults' command, but as someone mentioned, that requires the BSD subsystem to be installed. I usually assume it is.



[ Reply to This | # ]
great hint AppleScript preferences system
Authored by: kissedsmiley on Apr 07, '05 01:44:42AM

this is a _great_ hint because I had no clue we could do these things! Many times it's the discussion that "makes" the hint a super-hint... thank you to all



[ Reply to This | # ]