EventKit EKEventStoreChanged

In an attempt to write an applescript to register with EventKit so as to be notified about changes, I failed to find a method to register for notifications.


set theEKEventStore to current application's EKEventStore's alloc()'s init()

I was unable to find an applescript method to have NotificationCenter add an observer function to monitor EventStore as to its changes.

I have looked through Shane Stanley’s CalendarLib ES Suite commands, but could not find a reference to an EKEventStore object that posts an EKEventStoreChanged notification when EventKit Event Store detects changes to the Calendar database.

I’d greatly appreciate any direction or assistance in coding Applescript Objective C to gain control of this EventKit function.

My overall goal is to coordinate Apple’s ical with Filemaker Pro.

This is untested, but should be roughly what you want:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use script "CalendarLib EC" version "1.1.3"


set theEventStore to fetch store
-- start observing
current application's NSNotificationCenter's defaultCenter()'s addObserver:me selector:"eventStoreChanged:" |name|:(current application's EKEventStoreChangedNotification) object:theEventStore

-- end observing; makse sure you do this when done
current application's NSNotificationCenter's defaultCenter()'s removeObserver:me |name|:(current application's EKEventStoreChangedNotification) object:(missing value)

on eventStoreChanged:theNotification
	-- do stuff
end eventStoreChanged:

Apple’s Developer Documentation regarding ekeventstorechanged, states that although a notification is posted whenever changes are made to the Calendar database, individual changes are not. As such, the current notification method briefly pushes a dialog, but with no clear data as to the changes that occurred in an EKStore calendar.

What method of scripting an EKStore calendar, might I use to re-fetch stale EKEvent objects so as update their references in an external database, such as Filemaker Pro, and how would I capture the EKStore calendar data that had changed?

The documentation says “you should refetch all EKEvent and EKReminder objects you have accessed”. That basically means throw out everything you have and start again. The assumption is that you’re only interested in a small slice of the store at any time, and access it on a needs basis. If you’re duplicating it in another database, you’re probably going to have trouble keeping things synchronised.

How do I attach a notifier, from Objective C EventKit EventStore’s NSNotificationCenter, to a background process, such as a daemon or an agent?

My goal is to have a background process detect changes in the EventKit Store and then run or call an applescript.

You’d need to add the app as an observer of NSNotificationCenter’s defaultCenter using addObserver:selector:name:object:. It’s no different from handling any other notification.

I am revisiting this thread, since I have failed in achieving my goal from over 4 years ago.
My goal is to capture changes made to calendar or to an EKEvent when a user changes a Calendar’s time and date for a selected event.
It appears to me that I need an AppleScript that is always open to monitor for changes in EKEventStore’s database, and that via NSNotificationCenter captures the change in the event. I would like to capture its event info, title, start date, and UID.
With that AppleScript app always listening for NSNotificationCenter’s detection of EventStore’s database, I could create a database of the recent changes, and possibley write that information to a Filemaker script, which is my ultimate goal.

My first problem is that ScriptDebugger crashes with the code

 current application's NSNotificationCenter's defaultCenter()'s addObserver:**me**    selector:"eventStoreChanged:" |name|:(*current application's* EKEventStoreChangedNotification) object:theEventStore

After running the above line of AppleScript, ScriptDebugger immediately crashes after I apply any change in the Calendar app to an event.

If you have ideas on solving this problem, I would appreciate any instruction in writing the script.

I got it to work.

Here is the script. You have to save it as a stay-open application

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "EventKit"
use scripting additions

property ca : current application
property theEventStore : missing value
property eventList : {}
property currentEvent : missing value

on run
	set theEventStore to ca's class "EKEventStore"'s new()
	ca's NSNotificationCenter's defaultCenter()'s addObserver:me selector:"eventStoreChanged:" |name|:"EKEventStoreChangedNotification" object:theEventStore
end run

-- start of selectors
on eventStoreChanged:sender
	set end of my eventList to (|name| of sender) as text -- cant do UI in selector
end eventStoreChanged:
-- end of selectors

on quit
	ca's NSNotificationCenter's defaultCenter()'s removeObserver:me |name|:"EKEventStoreChangedNotification" object:theEventStore
	set theEventStore to missing value -- resets (probably not needed)
	continue quit
end quit

on idle
	if (count eventList) > 0 then
		set currentEvent to item 1 of eventList
		set eventList to rest of eventList
		tell me to display alert "Event Changed!" & return & (currentEvent) -- cant do UI in selector
		return 1
	end if
	return 5
end idle
1 Like

Does this maybe give us hope that broken AScripts (Satimage.osax) will be working again (with some rewriting)?

/

with best regards, Omar KN, Sweden