iOSのEventKitを使って標準カレンダーに予定を追加する

iOS 4?からプログラム側から標準のカレンダーに予定を追加することが出来るようになったようです。

詳しくはApple公式のEvent Kit プログラミングガイド(PDF)やサンプルコードの「SimpleEKDemo」を見てもらうとして、ここでは新規で予定を追加する時にタイトルや開始日時などをプログラム側から指定して予定を追加する画面を表示する方法を説明します。そして、今回はXcode 4 Previewを使ってサンプルを作ってみた。

まずはじめに、View-Based-Applicationなどでプロジェクトを作成します。

そして、Event Kitに必要なFrameworks「EventKit」「EventKitUI」を読み込みます。

ここでいきなりXcode 4だとXcode 3の様なFrameworkを追加する項目が見つかりません。。。

Xcode 4では「プロジェクトファイル>Build Phases>Link Binary With  Libraries」からFrameworkを追加するみたいです。

ヘッダーファイルでEventKitのFrameworkを読み込みます。

#import <eventkit /EventKit.h>
#import <eventkitui /EventKitUI.h>

viewDidLoadなどでイベントストアのインスタンスを作成します。EKEventStoreとはカレンダーの予定(Event)が入ったデータベース?みたい物でしょうか。

– (void)viewDidLoad {
  [super viewDidLoad];
  self.eventStore = [[[EKEventStore alloc] init] autorelease];
}

「予定を追加する」タイミングで[EKEvent eventWithEventStore:self.eventStore]で新規に追加するイベントオブジェクトを作ります。

EKEvent *event = [EKEvent eventWithEventStore:self.eventStore];

イベントオブジェクトのプロパティに登録したい情報を設定していきます。

event.title = @”This is title.”;
event.location = @”Tokyo, Japan.”;
event.startDate = [NSDate date];
event.endDate = [NSDate dateWithTimeIntervalSinceNow:86400];
event.notes = @”This is notes.”;

登録したイベント情報を画面上に表示して、ユーザーが変更できるように「EKEventEditViewController」のインスタンスを作成します。

EKEventEditViewController *eventEditViewController = [[[EKEventEditViewController alloc] init] autorelease];

変更、登録が終わったら、その通知を受け取るためのデリゲートを「eventEditViewController.editViewDelegate」で設定します。

eventEditViewController.editViewDelegate = self;

先ほど作ったイベントオブジェクトをイベント情報を表示する画面に渡します。

eventEditViewController.event = event;

そして、イベントストアも一緒に渡します。

eventEditViewController.eventStore = self.eventStore;

最後に、イベント情報をモーダル画面として表示します。 これで画面上にカレンダーの予定修正・追加画面が表示されると思います。

 [self presentModalViewController:eventEditViewController animated:YES];

「EKEventEditViewDelegate」を受け取ります。これはイベント情報画面が閉じられたときに呼ばれるようです。

– (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action

このデリゲート内でキャンセル、保存、削除の状態で分岐してイベントストアのセーブイベントでイベント情報を保存します。 EKEventEditViewControllerを表示せずにいきなりイベントストアのセーブイベントを読んで予定を追加することも出来るみたいです。

switch (action) {
  case EKEventEditViewActionCanceled:
    break;
  case EKEventEditViewActionSaved:
    [controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error];
    break;
  case EKEventEditViewActionDeleted:
    [controller.eventStore removeEvent:controller.event span:EKSpanThisEvent error:&error];
    break;
  default:
    break;
}

今回作ったサンプルはgithubに上げているので詳しくはコードを読んでください。