Adding Calendar Content to Your Application

In Leopard, your application can access and modify calendars, events, and to dos, by reading from and writing to Calendar Store using new Cocoa APIs. This means that your customers won't have to open iCal to check on their availability or to record commitments—your application can read from the same calendar data as iCal. And your application can write to the same Calendar Store that iCal uses. You can create an event or a to do in your application and it shows up immediately in iCal.

This article introduces you to Calendar Store and the related Cocoa APIs in Leopard. We'll explore the possible ways in which you can take advantage of the Calendar Store framework in your application by looking at the enhancements to Mail and the Calendar Dashboard Widget that are included in Leopard.

The Expanded Calendar Dashboard Widget

Take a look at the Calendar Dashboard Widget in Leopard. Notice that, compared with the Calendar widget in Tiger, there is now a third panel. (You may have to click on the widget to change between the one, two or three panel views.)

Calendar Widget with no Events

Figure 1: The New Calendar Dashboard Widget

The third panel displays any remaining events for today. Open up iCal and add some events to your schedule for today.

Adding Events in iCal

Figure 2: Adding Events in iCal

Now look back at the Calendar widget. All of the future events for today that fit in the panel are displayed. As the time for an event passes, the event is no longer listed in the panel. It's a quick way to survey what's coming up next in your day.

Calendar Widget with newly added events

Figure 3: Displaying Events in the Calendar Dashboard Widget

The Calendar Widget is able to access the same event data as iCal through Leopard's shared Calendar Store. Your application can access this data as well.

When you look at the widget, you might prefer to expose different information to the end user. With the Calendar Store framework you can do just that. In your application, you may decide whether or not to restrict the calendars from which you are displaying information. You may also choose whether to display events, to dos, or both and for what time frame. Let's see how you can read events and to dos from Calendar Store.

Reading from Calendar Store

The code needed to retrieve events from Calendar Store is surprisingly simple—just three steps.

The first step is to request a reference to the shared CalCalendarStore object that you use to communicate with Calendar Store. There is only one instance of CalCalendarStore per application so never create one directly. Here's an example:

CalCalendarStore *calStore = [CalCalendarStore defaultCalendarStore];

The second step is to form the predicate that defines your search parameters. If, say, you are querying for events you specify the start and end date for your search and the calendars you are searching. When you search for events you must always specify the time span that you want to search in by providing a start and end date. If you did not restrict the time span, recurring events would result in an unlimited number of events being returned by your query.

As an example, if you wanted to find all events that you have scheduled in the next week, your predicate looks like this:

NSPredicate *predicate = 
     [CalCalendarStore eventPredicateWithStartDate:[NSDate date]
	               endDate:[NSDate dateWithTimeIntervalSinceNow:(7 * 24 * 60 * 60)]
	               calendars:[calStore calendars]];

The last parameter in the predicate is an array of CalCalendar objects your events must belong to. The search described above is across all of the calendars in Calendar Store, but you can specify a subset of them.

The third step is to perform the search to return the events that match your predicate from the CalCalendarStore object:

NSArray *events = [calStore  eventsWithPredicate:predicate];	

Now that you have an NSArray containing all of the CalEvent objects you are interested in, you can decide what to do with them and how to display them.

The code required to read to dos to build your to do list is similar, also involving three steps. The first step is identical to the reference request above—to dos in the user interface are CalTask objects in Calendar Store.

In the second step you create a predicate designed to search for To Dos. With to dos you aren't required to specify a time span as there aren't recurring to dos. Because there are situations for which you may or may not be interested in time, there are four different methods that you use depending on what you are looking for:

Here's how you search all of your calendars for uncompleted to dos:

NSPredicate *predicate = 
     [CalCalendarStore taskPredicateWithUncompletedTasks:[calStore calendars]];

Finally, in the third step you generate an array of CalTask objects instead of CalEvent objects using this call:

NSArray *tasks = [calStore tasksWithPredicate:predicate];

CalTasks, CalEvents, and CalCalendarItems

The CalTask and CalEvent classes take advantage of the Objective-C 2.0 properties. The property names line up with the attributes you are used to setting by hand in iCal. For example, when you create a new event in iCal you see something like this.

Creating a new event

Figure 4: Creating a new Event

Some of the properties you see are common to both to dos and events and so are contained in CalCalendarItem which is the superclass to both CalTask and CalEvent. These include the title, alarms, url, notes, and calendar properties. The rest of the attributes you can set in iCal correspond to properties in the CalEvent class including the location, isAllDay, recurrenceRule, startDate, endDate, and attendees properties.

Now look at the dialog box in iCal when you create a new to do item.

Creating a new task

Figure 5: Creating a new to do Item

You can again see the title, calendar, url, and notes properties from the CalCalendarItem class. The new properties defined in the CalTask class are isCompleted, priority, and dueDate. Not shown in iCal but available to your application is the completedDate property.

Mail and Your to do List

Now that you can read from Calendar Store, you'd like to be able to write to dos and events as well. To understand the steps you use in your application to write to Calendar Store first consider what you do as an end user if you were creating a new event or To Do in iCal. For example, if you want to add a new to do to iCal, you create the to do, you enter the name, and associate the to do to a calendar. You might also set a priority level, a due date, set an alarm, and add some notes. Here is a simple to do in iCal, shown in Figure 6.

An example of a simple task

Figure 6: A sample to do

The moment you enter a to do into iCal, it is available to every other application through the Calendar Store framework, and this includes Mail (in Leopard).

Mail (version 3.1 as of this writing) includes support for Notes and a to do list. The to do you just entered in iCal is visible immediately in Mail. This means that users don't need to jump back and forth between Mail and iCal to manage their day.

Tasks in Mail.app

Figure 7: to dos in Mail

But Mail does more than just read from Calendar Store. You can create new to dos for your to do list in Mail and they appear in iCal. Click the to do button and a new line is added that you use to fill in the appropriate information.

Again, the point of this example is not to demonstrate how Apple applications implement to do item entry but how, as an application developer, all of this functionality is available for you to present from within your application in a way that makes sense to your customers.

To see the to do functionality in Mail from another perspective, click the Note button to create a new note. A window appears that is similar to what you see if you created a new mail message except that it looks like yellow notebook paper with additional options, as shown in Figure 8.

A Note view of the Task

Figure 8: A Note view of the to do

For example, you can create a corresponding to do by now pressing the to do button inside of this Note window. Type in the name of the to do and click the red arrow to the left of the to do and you get an information window (as shown in Figure 8) that allows you to specify a due date, set an alarm, set the priority level, and specify the calendar this to do item belongs to.

Now look back at iCal. You'll find the to dos you just created in Mail are now listed in order of the priorities you set.

Updated task list

Figure 9: Updated to do list

Writing to Calendar Store

Now let's see how easy it is to create a to do and save it to Calendar Store in your application. You follow the same basic steps for writing to Calendar Store that you followed for reading from it.

The first step is to create a new CalTask object:

CalTask *newTask = [CalTask task];

Now you can set the appropriate properties to configure this to do. For example, adding a high priority to do item to clean your office today to the first calendar in the list of available calendars looks like this:

newTask.calendar = [[[CalCalendarStore defaultCalendarStore] 
                                       calendars] 
                                       objectAtIndex:0];
newTask.title = @"Clean Office";
newTask.priority = CalPriorityHigh;
newTask.dueDate = [NSDate date];

The final step is to save your new to do to Calendar Store:

[[CalCalendarStore defaultCalendarStore] saveTask:newTask
                                            error:&err];

As you expect, the steps are the same to create a new CalEvent object:

CalEvent *event = [calEvent event];

Add your information to the event. Set the start and end times, the name of the event, and be sure to specify which calendar you are adding the event to. For example, here's an event to catch up on your email during the next hour:

newEvent.calendar = [[[CalCalendarStore defaultCalendarStore] 
	                                    calendars] 
	                                    objectAtIndex:0];
newEvent.title = @"Catch up on email";
newEvent.startDate = [NSDate date];
newEvent.endDate = [NSDate  dateWithTimeIntervalSinceNow:3600];

You can now save the event to Calendar Store:

[[CalCalendarStore defaultCalendarStore] saveEvent:newEvent
                                         span:CalSpanThisEvent
                                         error:&err];

Summary

These examples demonstrate the power of Leopard's Calendar Store framework and the ease with which you can incorporate to dos and event features into your application. Because Calendar Store is shared by iCal, Mail, and the Calendar Widget, using it in your application allows you to provide a more integrated user experience and allows users to access events and to dos they create in your application even when it isn't running.

Get Started with Leopard

The next generation of the world's most advanced operating system is now available. Tap into the innovative technologies of Mac OS X Leopard and design your products with new and compelling features. With an ADC Premier or Select Membership, you have a range of developer resources from Apple engineers and experts, including ADC on iTunes, Coding Headstarts, the ADC Compatibility Labs and more. Learn how ADC Memberships provide you Apple expertise. From code to market.

Posted: 2007-11-30

 
 
 

Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2009 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice