Exposing SharePoint calendars for iCalendar clients

Hello there,

since Sharepoint offers out-of-the-box calendar and scheduling capabilities, it is a nice option for teams in terms of improved collaboration and sharing common agendas. By default, users can access the MOSS calendars using a browser or by syncing it with their Microsoft Outlook clients. Additionally, a RSS subscription is also available.
So far, so good, but if we need to subscribe to the calendar using a Mac or an iPhone, iPad, or any other client supporting the iCalendar specification, we have to use a custom solution.

Simply put, a file with the content type text/calendar needs to be generated, and it has to more or less comply with the RFC 2445 specification. Of course you may want to implement it your way from scratch, but there’s a nice iCal Exporter kit from CodePlex. It has been developed as a MOSS feature, but you can easily adapt it to serve users in a different way, for example as a custom http handler. So one can create a class inheriting the IHttpHandler interface, deploy the class library onto the Sharepoint application, and register the handler in web.config:

<add verb="GET,POST" path="*/ical.ics" type="MyLibrary.MyIcalHandler" />

Then we could access the generated file for example via http://myhost/mysite/lists/calendar/ical.ics , and subscribe to the calendar in a corresponding client software. In the handler itself, based on the request URL, we can fetch the corresponding Sharepoint list, iterate through its items and generate the proper entries, then flush it to the browser. The iCal Exporter kit also deals with recurring calendar entries, deleted event series’ occurences, all-day events, so that almost every case is covered.

One thing worth mentioning: when generating an event entry, be careful using the DTSTAMP property. In order for iCal clients to properly recognize changes made to calendar entries, one has to assign the last-modified-date property of the corresponding SPListItem as DTSTAMP value:

 foreach (SPListItem item in calendarList.Items)
    // write vevent start...
    DateTime modified = Convert.ToDateTime(item["Modified"]);
    String dtstamp = "DTSTAMP:" + modified.ToString("yyyyMMddTHHmmssZ");
    // write dtstamp, other properties, vevent end

Otherwise you may encounter a problem that the client won’t fetch a calendar entry’s changes.

Hope this helps,