Is there a way to make the properties in this script persistent?

EDIT: I’ve just thought of another way to tackle this problem that avoids putting the Login Request into the handle_string handler, so no need to solve this one, I think I’ll be OK. :slight_smile:

Hello,

I’m getting some help with another part of my Twitter Updating script on another thread, but while I’m waiting for an answer to my last question, I decided to work on another part of my script and ran into a different problem. (I hope it’s not bad etiquette to open multiple threads on the same project… If so, please let me know and I won’t do it again. :slight_smile: )

Anyway, I thought it would be nice for the user experience if my script asked for their Twitter username and password and then stored it in some properties so they wouldn’t have to do it again. I wrote this and it worked fine on its own:


property TwitterUser : ""
property TwitterPassword : ""


if TwitterUser is "" or TwitterPassword is "" then
	repeat
		display dialog "Please enter your Twitter username. (You should only have to do this once.)" default answer ""
		if (text returned of result) is not "" then
			set TwitterUser to text returned of result
			display dialog TwitterUser
			exit repeat
		else
			display dialog "You didn't enter a username."
		end if
	end repeat
	
	repeat
		display dialog "Please enter your Twitter password" default answer ""
		if (text returned of result) is not "" then
			set TwitterPassword to text returned of result
			display dialog TwitterPassword
			exit repeat
		else
			display dialog "You didn't enter a password."
		end if
	end repeat
else
	display dialog TwitterUser & return & TwitterPassword
end if

But the ultimate goal was to include it in a script that would be launched using LaunchBar, whose behavior is to prompt you for text after you call up the script and hit the space bar and then (I think I’m understanding this correctly) uses the handler handle_string() to send your text along to an AppleScript to use. My problem is that when I placed the above scriptlet into the script that responds to that handler, the properties seem to no longer persist. They work fine within that script – I can use them to send out a Tweet after they are entered – but the next time the script is run you have to enter the same information all over again.

My question is – is there something I’m missing that would get the property values to be persistent? Or is my only solution to save the username and password in a text file to be read again in the future?

For reference, here is the relevant section of the script in question:

property TwitterUser : ""
property TwitterPassword : ""


on handle_string(s)
	
	display dialog TwitterUser & return & TwitterPassword
	
	-- First, check the character limit.  If the tweet is over the limit, give an error with number of characters in the attempted Tweet.
	
	set theCharacterCount to count (s)
	if theCharacterCount is greater than 140 then
		display dialog "Error: more than 140 characters (" & theCharacterCount & " characters in total)"
		
		--If the Tweet is within the character limit, get the userinfo and turn the Tweet into an instruction to update Twitter using cURL!
		
	else
		GetUserInfo()
		set TwitterUpdate to "curl -u " & TwitterUser & ":" & TwitterPassword & " -d status=\"" & s & "\" [url=http://twitter.com/statuses/update.xml]http://twitter.com/statuses/update.xml"[/url]		
		UpdateTwitter(TwitterUpdate, s)
	end if
end handle_string

on GetUserInfo()
	
	-- check to see if the username and password have already been entered
	
	if TwitterUser is "" or TwitterPassword is "" then
		
		-- if not, then request them
		repeat
			display dialog "Please enter your Twitter username. (You should only have to do this once.)" default answer ""
			if (text returned of result) is not "" then
				set TwitterUser to text returned of result
				display dialog TwitterUser
				exit repeat
			else
				display dialog "You didn't enter a username."
			end if
		end repeat
		
		repeat
			display dialog "Please enter your Twitter password" default answer ""
			if (text returned of result) is not "" then
				set TwitterPassword to text returned of result
				display dialog TwitterPassword
				exit repeat
			else
				display dialog "You didn't enter a password."
			end if
		end repeat
	else
		
		-- if so, display them
		
		display dialog TwitterUser & return & TwitterPassword
	end if
end GetUserInfo

Is there something this beginning AppleScripter is missing? Thanks in advance for your help! :slight_smile:

Alex

if you save the script as application, then the property values are persistent.
Alternatively use a embedded script object which can be saved as a preference file

StefanK,

Thank you. While saving it as an application wouldn’t have worked for this – LaunchBar needs the script it sends to to be a script and not a script application – that’s good for me to know for the future. I’m sure I’ll run into this again sometime. And I’ll look into “embedded script objects”-- the ability to save preference files sounds like something good to know how to do. :slight_smile:

I very much appreciate your help and experience,

Alex

A solution that might work is to save a “preferences” script application which could hold the persistent property and load it when needed. If you save the script as a bundle then you could have the preferences script saved into the bundle and everything should travel well together as well. See this thread http://bbs.macscripter.net/viewtopic.php?id=22264 for an example and hopefully an explanation of what is happening.

There are a couple of ways to write a prefs file for your script:

HHAS method:

property _prefs : {foo:1, bar:"hello"} -- [a record containing your persistent preferences]

on _prefsFile()
	return POSIX file (POSIX path of (path to preferences) & "MyAppletPrefs") -- [your prefs filename here]
end _prefsFile

on loadPrefs()
	try
		set _prefs to read _prefsFile() as record
	on error number -43 -- file not found; use default values
	end try
end loadPrefs

on savePrefs()
	set f to open for access _prefsFile() with write permission
	write _prefs to f as record
	close access f
end savePrefs

JohnM method:

(*  It is important that the name of the domain is unique.  'defaults write' writes a plist file in your preferences folder, if one already exists with that name the preference will be written into it (overwriting one with the same key if it exists).*)

set myPrefDomain to "com.myUniqueDomain.myPrefs"
-- something that's not likely to be used by anyone else

set myVar to text returned of (display dialog "What do you want saved?" default answer "I'd like this saved.")
--Write to your Prefs folder
do shell script "defaults write " & myPrefDomain & " myVar " & quoted form of myVar

--Read from your prefs folder
set myStored to do shell script "defaults read " & myPrefDomain & " myVar"
display dialog myStored

@ jerome

Thank you – that’s useful for me to know.

@ Adam Bell

And ooh, that JohnM method seems pretty cool. (And ultimately user friendly – if they want to reset something, you can tell them just to delete the prefs – no need to mess with Script Editor or resaving the script application.

One question, how would have the script deal with the situation if that preference file was missing? (For example, if the reader did delete the preference file, I’d want them to be prompted to reenter the information. How would one do that?)

Thanks for your help!

Alex

If you try to read it, it will error so:

(*  It is important that the name of the domain is unique.  'defaults write' writes a plist file in your preferences folder, if one already exists with that name the preference will be written into it (overwriting one with the same key if it exists).*)

set myPrefDomain to "com.myUniqueDomain.myPrefs"
-- something that's not likely to be used by anyone else

(*set myVar to text returned of (display dialog "What do you want saved?" default answer "I'd like this saved.")
--Write to your Prefs folder
do shell script "defaults write " & myPrefDomain & " myVar " & quoted form of myVar*)

--Read from your prefs folder
try
	set myStored to do shell script "defaults read " & myPrefDomain & " myVar"
	display dialog myStored
on error e
	if e contains "does not exist" then display dialog "You tossed it" -- just for demonstration, no need for this, just ask for the data again.
	set myVar to text returned of (display dialog "What do you want saved?" default answer "I'd like this saved.")
	--Write to your Prefs folder
	do shell script "defaults write " & myPrefDomain & " myVar " & quoted form of myVar
end try

Great, thank you, I’ll try that out! :slight_smile: