Scripting iCal on Snow Leopard woes...

Apple has changed the scripting behavior on the buggy iCal once again, making old work-arounds no longer work. Looking for viable new work arounds.

  1. When fetching properties of events, in Leopard many properties would actually be missing values but return an undefined variable. in Leopard, I worked around that like this:

set someloc to location of some_event
		try
			set testit to someloc
		on error
			set someloc to ""
		end try

now they actually DO property return missing value, so that work around code can be changed to this:


set someloc to location of some_event
		try
			set testit to someloc
			if someloc is missing value then set someloc to ""
		on error
			set someloc to ""
		end try

so far so good. but…

  1. what about SETTING the missing value? At least for some properties, you get an error:

tell application "iCal"
	set te to some event of calendar "Testing" whose summary contains "testing event"
set recurrence of te to missing value
end
end tell

result:
error “iCal got an error: Can’t make missing value into type text.” number -1700 from missing value to text

huh? now it wants text?

ok so…

  1. if you set the recurrence property to a blank string (“”) then it works without error, however the event does not actually SHOW UP in the iCal GUI.

When you set the recurrence (repeat) to NONE in the iCal GUI, the property is actually changed back to missing value.

Huh? so what’s the work around now?

  1. Tiger to Snow Leopard compatibility and event ID/UID.

This is untested so far, but to retain Tiger backwards compatibility in Leopard, I had to use:


if hasleopard then
					set good_event to some event of calendar t_cal whose uid is t_id
					--set good_event to some event of calendar t_cal whose uid is t_id -- when compiled on Leopard
					--set good_event to some event of calendar t_cal whose id is t_id -- when compiled on tiger
				else
					set good_event to some event of calendar t_cal whose uid is t_id
					--set good_event to some event of calendar t_cal whose «class wr10» is t_id -- when compiled on Leopard
					--set good_event to some event of calendar t_cal whose uid is t_id -- when compiled on Tiger
				end if

Can’t recall for sure now, but this <> used to compile correclty for use in Tiger… Now it compiles as UID in both cases. Still needs testing.

WoodenBrain,

You’re absolutely correct reference the iCal UID breakage in Snow Leopard. UID now compiles to «class wr10» in Snow Leopard/Xcode 3.2. This essentially breaks compatibility with Leopard. I had been using the «class wr10» workaround to maintain compatibility with Tiger. Tiger compatibility seems to remain intact.

It doesn’t seem as though Apple is seriously committed to maintaining AppleScript compatibility from OS to OS. Which makes it kinda frustrating when you’re working on a widely distributed AppleScript Studio App. I’m now going to have to maintain multiple versions for specific OS’s and even consider downgrading to compile for earlier system versions.

If anyone has any sort of workaround, please chime in!

I can’t speak for Leopard or SL, but in Jaguar and Tiger:

  1. Although getting the location of an event returns nothing at all if no location has been specified, if you get the ‘properties’ of the event, the ‘location’ of the resulting record is reliably ‘missing value’. I imagine this would work on any system:
tell application "iCal"
	set someloc to location of (get properties of some_event)
	if (someloc is missing value) then set someloc to ""
end tell

2./3. Setting a ‘location’ to “” clears it. However, the same doesn’t work for a ‘recurrence’. The only way I’ve found to clear a recurrence (short of deleting the event and starting again) is to set another recurrence with an ‘until’ date that’s earlier than the event’s ‘start date’:

tell application "iCal"
	set recurrence of some_event to "FREQ=DAILY;UNTIL=10000101" -- Until 1 January 1000.
end tell

I think the above are weaknesses in iCal’s AppleScript implementation. You shouldn’t have to resort to tricks like these.

  1. It’s not clear what’s being said here. Putting together WoodenBrain’s script with 2ndSegment’s comment, I gather that the class code for ‘uid’ is different in iCal 3.0 from that in earlier and later versions. (If so, it’s a goof in iCal’s AppleScript implementation, not in AppleScript itself.) The following would probably work with all versions, but I’m not sure if ‘run script’ works in AppleScript Studio:
tell application "iCal"
	set good_event to (run script "on run {t_cal, t_id}
	tell application \"iCal\" to return first event of calendar t_cal whose uid is t_id
end run" with parameters {t_cal, t_id})
end tell