Write to plist with space character?

Hi guys,

I’m trying to write preferences to a Plist which contain a space character. I’ve found a way to do this with the following code but it seems overly complex. Is there a simpler and more effective way of doing this?

property thePlist : (path to preferences folder as Unicode text) & "testapp.preferences"
property pathPlist : ""
property newString : ""
property charName : ""


tell application "Finder"
	set pathPlist to POSIX path of thePlist
end tell


writeDefault("Name", "My Name")

display dialog readDefault("Name")

on readDefault(nameP)
	set valueP to do shell script "defaults read " & pathPlist & space & nameP
	set charName to every character of valueP
	set newString to ""
	repeat with charsRef in charName
		if contents of charsRef is "_" then
			set newString to newString & space
		else
			set newString to newString & charsRef
		end if
	end repeat
	return newString
end readDefault


on writeDefault(nameP, valueP)
	set charName to every character of valueP
	set newString to ""
	repeat with charsRef in charName
		if contents of charsRef is space then
			set newString to newString & "_"
		else
			set newString to newString & charsRef
		end if
	end repeat
	set valueP to newString
	do shell script "defaults write " & pathPlist & " " & nameP & " " & valueP
end writeDefault

Hi,

“the simplest and most effective way” is to avoid spaces in the value :wink:
Alternatively you can use AppleScript’s text item delimiters to “convert” the string

property thePlist : (path to preferences folder as Unicode text) & "testapp.preferences"
property pathPlist : ""

set pathPlist to quoted form of POSIX path of thePlist

writeDefault("Name", "My Name")

display dialog readDefault("Name")

on readDefault(nameP)
	set valueP to do shell script "defaults read " & pathPlist & space & nameP
	return convertString(valueP, "_", space)
end readDefault

on writeDefault(nameP, valueP)
	set valueP to convertString(valueP, space, "_")
	do shell script "defaults write " & pathPlist & " " & nameP & " " & valueP
end writeDefault

on convertString(valueP, f, t)
	set {TID, text item delimiters} to {text item delimiters, f}
	set valueP to text items of valueP
	set text item delimiters to t
	set valueP to valueP as text
	set text item delimiters to TID
	return valueP
end convertString

Hi,

It would be easier to use a subroutine with AppleScript’s text item delimiters and call it from your other subroutines. Something like this:


set t to "My Name"
set t to ReplaceText(t, space, "_")
--
on ReplaceText(t, s, r)
	set utid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to s
	set temp_list to text items of t
	set AppleScript's text item delimiters to r
	set temp_text to temp_list as string
	set AppleScript's text item delimiters to utid
	return temp_text
end ReplaceText

Edited: and btw, I pretty sure you can have spaces in keys. When you write to the plist use quotes:

do shell script “defaults write ~/Desktop/some.domain ‘some key’ ‘some string’”

gl,

That is excellent!

Unfortunately it creates an error in ASS when one of the values is not a string but, for example, a boolean.

In AppleScript I can solve this easily by checking for class is string:

on ReplaceText(t, s, r)
	if class of t is string then
		set utid to AppleScript's text item delimiters
		set AppleScript's text item delimiters to s
		set temp_list to text items of t
		set AppleScript's text item delimiters to r
		set temp_text to temp_list as string
		set AppleScript's text item delimiters to utid
		return temp_text
	else
		return t
	end if
end ReplaceText

If I run the same code in ASS this doesn’t work…

Oddly, if I ask for the class of a string value it returns with a number (display dialog class of t >> 1413830740). Unfortunately the following adaptation doesn’t work. The same is true for Stefan’s method. I can solve this in my app by separating the handling of the different classes of variables but am still curious if it can be solved more directly…

on ReplaceText(t, s, r)
	if class of t is 1413830740 then
		set utid to AppleScript's text item delimiters
		set AppleScript's text item delimiters to s
		set temp_list to text items of t
		set AppleScript's text item delimiters to r
		set temp_text to temp_list as string
		set AppleScript's text item delimiters to utid
		return temp_text
	else
		return t
	end if
end ReplaceText

Ha, solved it!

on ReplaceText(t, s, r)
	set valClass to (class of t) as string
	if valClass is "string" then
		set utid to AppleScript's text item delimiters
		set AppleScript's text item delimiters to s
		set temp_list to text items of t
		set AppleScript's text item delimiters to r
		set temp_text to temp_list as string
		set AppleScript's text item delimiters to utid
		return temp_text
	else
		return t
	end if
end ReplaceText