Hi,
I am attempting to save a couple of user settings to a file and I believe that the correct place for the file is in user/library/application support/AppName/filename.ext
I found a block of code published in “Applescript The Definitive Guide” by Matt Neuburg 2nd Edition Covers Mac OS Tiger, published in 2006 . So only nineteen years old.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
# Test bed of saving user settings and of usin vanila dialogs
set tPathAppSup to (path to application support from user domain) & "myPrefs.scpt"
script myPrefs
property DestinationPath : ""
property FormatString : ""
end script
try
set myPrefs to load script file tPathAppSup
on error
set DestinationPath of myPrefs to "A/Posix/Path"
set FormatString of myPrefs to "%Y/%Y-%M/%f.%e"
store script myPrefs in file tPathAppSup replacing yes
-- ERROR: Can’t make file {alias "Macintosh HD:Users:skids:Library:Application Support:", "myPrefs.scpt"} into type file.
end try
display dialog "The prefs are set as follows DestinationPath : " & DestinationPath of myPrefs & " FormatString : " & FormatString of myPrefs
The issue is that the line set tPathAppSup to (path to application support from user domain) & "myPrefs.scpt" is returning a list with two items with item 1 an alias HFS file path and the second a string. So it appears that sometime in the past Applescript changed how the path command works.
I have no real idea how to add a sub folder and file name to an alias to an HFS path and have tried many permutations with both PosixPaths and HFS paths but so far I have been unable to create and write to the file. For example the following version also fails:
# Test bed of saving user settings and of usin vanila dialogs
set tPathAppSup to (path to application support from user domain)
set tPath to contents of tPathAppSup as text
display dialog tPath
set tPath to tPath & "Ingester:IngestPrefs.scpt"
display dialog tPath
script myPrefs
property DestinationPath : ""
property FormatString : ""
end script
try
set myPrefs to load script file tPathAppSup
on error
set DestinationPath of myPrefs to "A/Posix/Path"
set FormatString of myPrefs to "%Y/%Y-%M/%f.%e"
store script myPrefs in file tPath replacing yes
-- ERRORS : An error of type -4960 has occurred.
end try
display dialog "The prefs are set as follows DestinationPath : " & DestinationPath of myPrefs & " FormatString : " & FormatString of myPrefs
Please tell me how to get the code working.
A couple of further questions.
First I note that the HFS path starts with the name of the drive e.g.
“Machintosh HD” and that this is removed when the alias is converted using POSIX PATH. Does this imply that a posix path defaults to the system volume unless a volume name is present?
tPathAppSup to (path to application support from user domain as text) & "myPrefs.scpt"
The as text in this case is an optional parameter of the path to command, not the AppleScript coercion.
The list you’re seeing is what happens when concatenating items of different classes. If the second can’t be coerced to the same class as the first, the result is instead a list containing the two items.
Sort of. With a different volume, the path would be along the lines of “\Volumes\volumeName\…”. There are a couple of other variations that shell scripters sometimes use, but what you say is generally true for AppleScript’s conversions between HFS and POSIX paths.
Thank you for your correction. I could have sworn that I had tried as text but obviously not. I’m going to have to get use to using the HFS format which feels alien to me. Mind you a lot of Applescript almost seems designed to trip me up. For example it appears that the file command only creates a file and is incapable of creating a folder grrrr.
My final working script now looks like this:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
# Test bed of saving user settings and of usin vanila dialogs
set tPathAppSup to (path to application support from user domain as text)
MakeFolder(tPathAppSup, "IngestImages")
set tPathAppSup to tPathAppSup & "IngestImages:IngestImagesPrefs.scpt"
display dialog tPathAppSup
script myPrefs
property DestinationPath : ""
property FormatString : ""
end script
try
set myPrefs to load script file tPathAppSup
on error
set DestinationPath of myPrefs to "A/Posix/Path"
set FormatString of myPrefs to "%Y/%Y-%M/%f.%e"
store script myPrefs in file tPathAppSup replacing yes
end try
display dialog "The prefs are set as follows DestinationPath : " & DestinationPath of myPrefs & " FormatString : " & FormatString of myPrefs
on MakeFolder(pPath, pName)
try
tell application "Finder"
make new folder at folder pPath with properties {name:pName}
end tell
on error terror
log terror
end try
end MakeFolder
Peavine made reference to this thread over on the code exchange forum : Saving Persistent Values - #8 by bmose
where he posted a more generalised form of the code posted above. I found the prefs code on, I think, stack exchange and thought it would meet my needs.
In his post Peavine makes a passing comment that implies the location of the read and write handlers are important with the read having to be placed at the top and the write at the bottom of the main script:
The get handler would normally be placed at the beginning of the script:
set thePreferences to getPreferences() --returns a list of two values
on getPreferences()
set theScript to (path to preferences as text) & "test.scpt" --set to desired value
try
set thePreferences to load script file theScript
return {preferenceOne of thePreferences, preferenceTwo of thePreferences}
on error
return {"Default Value One", "Default Value Two"} --set to desired values
end try
end getPreferences
The write handler would normally be placed at the end of the script:
writePreferences("Test Value One", "Test Value Two")
on writePreferences(valueOne, valueTwo)
set theScript to (path to preferences as text) & "test.scpt" --set to desired value
script thePreferences
property preferenceOne : valueOne
property preferenceTwo : valueTwo
end script
store script thePreferences in file theScript replacing yes
end writePreferences
type or paste code here
Would someone explain why the position of the handlers is important?
@peavine will have to answer this himself, of course. But I suspect he means that the calls to the handlers he’s written to implement the script file idea in one of his own scripts in that thread should be placed at the beginning and end of the script’s run handler code. The handlers themselves should be grouped together at one end of the script or the other, as is best practice.
Simon. Thanks for looking at my post. As you and Nigel have already concluded, I should have used the word called instead of placed. FWIW, a simple example:
set savedNumber to getNumber()
set calculatedNumber to (savedNumber + 1)
display dialog "The result of the calculation is " & calculatedNumber
writeNumber(calculatedNumber)
on getNumber()
set theFile to (path to preferences as text) & "test.scpt" --set to desired value
try
set theScript to load script file theFile
return theValue of theScript
on error --typically when the script file does not exist
return 0
end try
end getNumber
on writeNumber(theNumber)
set theFile to (path to preferences as text) & "test.scpt" --set to same value as above
script theScript
property theValue : theNumber
end script
store script theScript in file theFile replacing yes
end writeNumber