I need to add new items to a Plist file that already exists
First I want to check if a name exists if so adjust the name
add the item to the list (here it doesn’t work)
-- The item name consist of Testxxxx where the xxxx has to range between 4999 and smaller
set thePlistItemNameNumber to "4999"
set thePlistItemName to "Test" & thePlistItemNameNumber
tell application "System Events"
tell property list file "/Library/Preferences/com.myPListFile.plist"
tell contents
-- check if Test4999 exists end if so make another name
if property list item thePlistItemName exists then
set thePlistItemNameNumber to thePlistItemNameNumber - 1
set thePlistItemName to "Test" & thePlistItemNameNumber
repeat while property list item thePlistItemName exists
set thePlistItemNameNumber to thePlistItemNameNumber - 1
set thePlistItemName to "Test" & thePlistItemNameNumber
end repeat
end if
-- here I trie to add the new item but it doesn't take the name Test4999 just displays "thePlistItemName"
set previousValue to value
set value to (previousValue & {|thePlistItemName|:"Test"})
end tell
end tell
end tell
display dialog thePlistItemName
Here is a handler (or better two handlers) that I wrote a while ago. Maybe they are helpful to you. I think the second one is more correct, but I haven’t played around with them in a while. Both of them seem to work fine.
To test it, create a plist “test.plist” on your desktop with the following content:
Then run the following test-script. You should then have 4 new keys in your plist.
set pListPath to POSIX path of (path to desktop) & "test.plist"
-- using addKey
addKey(pListPath, "testKey2", "file2")
addKey(pListPath, "testKeyArray3", {"list3", 33})
-- using addKey2
addKey2(pListPath, "testKey4", "file4", text)
addKey2(pListPath, "testKeyArray5", {"list5", 55}, list)
-- -- -- -- -- -- HANDLERS
--c-- addKey(posixPath, keyname, keyValue)
--d-- Add property item to existing plist. Case of key name is preserved.
--d-- Case is not preserved for subkeys in records unless properly piped.
--a-- posixPath : string -- posix path to plist
--a-- keyname : string -- name of new property
--a-- keyValue : anything
--r-- nothing
--x-- addKey(plistPath, "NewKey", {"ABC", 33}) --> new key in plist
--u -- ljr_nbg
on addKey(posixPath, keyname, keyValue)
local posixPath, keyname, keyValue
local newStr, chars, lst, scpt, oldStr, ASTID
set ASTID to AppleScript's text item delimiters
try
--escape backslashes and pipes in the identifier-to-be
set keyname to keyname as string
repeat with chars in {{"\\", "\\\\"}, {"|", "\\|"}}
set {oldStr, newStr} to chars
if oldStr is in keyname then
set AppleScript's text item delimiters to oldStr
set lst to keyname's text items
set AppleScript's text item delimiters to newStr
set keyname to lst as string
end if
end repeat
set keyname to "|" & keyname & "|"
set AppleScript's text item delimiters to ASTID
set scpt to "script\r\ton fn(posixPath,keyValue)\r\t\ttell application " & ¬
"\"System Events\"\r" & "\t\t\ttell property list file posixPath\r" & ¬
"\t\t\t\ttell contents\r\t\t\t\t\tset previousValue to value\r\t\t" & ¬
"\t\t\tset value to (previousValue & {" & keyname & ¬
":keyValue})\r\t\t\t\tend tell\r\t\t\tend tell\r\t\tend tell\r\tend" & ¬
" fn\t\rend script"
fn(posixPath, keyValue) of (run script scpt)
on error eMsg number eNum
set AppleScript's text item delimiters to ASTID
error "Can't addKey: " & eMsg number eNum
end try
end addKey
--c-- addKey2(posixPath, keyname, keyValue, keyType)
--d-- Add property item to existing plist. Case of key name is preserved.
--d-- Case of subkey names in records is also preserved.
--a-- posixPath : string -- posix path to plist
--a-- keyname : string -- name of new property
--a-- keyValue : anything
--a-- keyType : AppleScript class supported by plist
--r-- nothing
--x-- addKey2(plistPath, "NewKey", {"ABC", 33},list) --> new key in plist
--u -- ljr_nbg
on addKey2(posixPath, keyname, keyValue, keyType)
local posixPath, keyname, keyValue, plistFile
local keyType
try
tell application "System Events"
set plistFile to property list file posixPath
make new property list item at end of property list items ¬
of contents of plistFile with properties ¬
{kind:keyType, name:keyname, value:keyValue}
end tell
on error eMsg number eNum
error "Can't addKey2: " & eMsg number eNum
end try
end addKey2
Your handler adds new keys to the plist file but i still have two problems:
when i change the type to number instead of text it still adds the key as string
one of my values is a path to a directory that should be in the volumes:external drive:dir1:subdir2: format
but it always ends up being written as /volumes/external drive/dir1/subdir2
→ i’ve tested and this format isn’t accepted by the application that uses the plist
Any help would be very appreciated!
set directoryPath to choose folder with prompt "Choose the folder:" default location the path to home folder
set pListPath to POSIX path of (path to desktop) & "test.plist"
addKey2(pListPath, "testKey4", "4", number)
addKey2(pListPath, "testKey5", directoryPath, string)
on addKey2(posixPath, keyname, keyValue, keyType)
local posixPath, keyname, keyValue, plistFile
local keyType
try
tell application "System Events"
set plistFile to property list file posixPath
make new property list item at end of property list items ¬
of contents of plistFile with properties ¬
{kind:keyType, name:keyname, value:keyValue}
end tell
on error eMsg number eNum
error "Can't addKey2: " & eMsg number eNum
end try
end addKey2
remove the quotes from your integer or coerce! Try this:
addKey2(pListPath, "testKey4", "5", number) --> addes as string since you provide a string
addKey2(pListPath, "testKey5", "5" as integer, number) --> added as integer (string coerced to integer)
addKey2(pListPath, "testKey6", 5, number) --> added as integer since that what is already is
As to your second question:
Aliases are converted to posix paths automatically.
If you really want to preserve Mac-like paths, try this:
set pListPath to POSIX path of (path to desktop) & "test.plist"
set pListAlias to POSIX file pListPath as alias --> now it is an alias
set pListAliasString to pListAlias as string --> now it is a string
addKey2(pListPath, "testKey9", pListAliasString, text) --> Mac-like path in plist
Note that you will always have to coerce it to an alias when reading it back in. So it doesn’t actually matter whether you have a Mac-like or a posix path:
posix file "/Users/yourName/Desktop/test.plist" as alias --> an alias
"Mac:Users:yourName:Desktop:test.plist" as alias --> an alias
And since I was talking about reading keys back in, I should give you this handler:
--c-- readKey(posixPath, keyname)
--d-- Read value of existing key in existing plist.
--a-- posixPath : string -- posix path to plist
--a-- keyname : string -- name of property (case-sensitive)
--r-- anything -- value of key
--x-- readKey(thePListPath, "User Email") --> value of key in plist
--u -- ljr_nbg
on readKey(posixPath, keyname)
local posixPath, keyname, val
try
tell application "System Events"
tell property list file posixPath
tell contents
set val to value of property list item keyname
end tell
end tell
end tell
return val
on error eMsg number eNum
error "Can't readKey: " & eMsg number eNum
end try
end readKey
Hope this helps!
(Info: I edited post #7 to answer your second question)