読者です 読者をやめる 読者になる 読者になる

hachinoBlog

hachinobuのエンジニアライフ

EventKitを使ってカレンダーに登録する方法(iOS5系)

アプリ内の情報を端末カレンダーに送信するメモ
1. EventKit.frameworkを入れる
2. EKEventStoreのインスタンス生成 (初期化して解放まで重いのでシングルトンとかにして使い回す設計にする)
3. EKEventのインスタンスを生成してタイトルなど送信したい情報をセットする
セットできるのは[タイトル]、[場所]、[開始時間]、[終了時間]、[メモ]、[アラーム通知時間]など

下記EKEventStoreのシングルトンクラスを作成

//MyEventManager.h

#import <Foundation/Foundation.h>
#import <EventKit/EventKit.h>

@interface MyEventManager : NSObject

@property (nonatomic, retain) EKEventStore *sharedEventKitStore;
+ (MyEventManager *)sharedInstance;

@end

//MyEventManager.m

#import "MyEventManager.h"

@implementation MyEventManager

static MyEventManager *_sharedInstance;

+ (MyEventManager *)sharedInstance
{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    
    return _sharedInstance;
    
}

+ (id)allocWithZone:(NSZone *)zone {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [super allocWithZone:zone];
    });
    
    return _sharedInstance;
    
}

- (id)init {
    self = [super init];
    if (self) {
        _sharedEventKitStore = [[EKEventStore alloc] init];
    }
    
    return self;
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain
{
    return self;
}

- (unsigned)retainCount
{
    return UINT_MAX;  // 解放できないオブジェクトであることを示す
}

- (oneway void) release {}
//- (void)release
//{
//    // 何もしない
//}

- (id)autorelease
{
    return self;
}

- (void)dealloc {
    [_sharedEventKitStore release];
    [super dealloc];
}

@end

呼び出し側のコードは

MyEventManager *eventMg = [MyEventManager sharedInstance];
EKEvent *event = [EKEvent eventWithEventStore:eventMg.sharedEventKitStore];
[event setTitle:@"寝る"]; //タイトル
[event setLocation:@"ベット"]; //場所
[event setTimeZone:[NSTimeZone defaultTimeZone]]; //タイムゾーン
[event setStartDate:[NSDate dateWithTimeIntervalSinceNow:(60*10)]]; //開始時刻を10分後に設定
[event setEndDate:[NSDate dateWithTimeIntervalSinceNow:(60.0f*20)]]; //終了時刻を20分後に設定
[event setCalendar:self.sharedEventKitStore.defaultCalendarForNewEvents];

//アラーム通知時刻をイベント開始5分前に設定
NSTimeInterval timer = -60*5; //5分前
EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:timer];
[event addAlarm:alarm];

//登録処理
NSError *error = NULL;
BOOL result = [eventMg.sharedEventKitStore saveEvent:event span:EKSpanThisEvent commit:YES error:&error];

削除処理の場合は

NSDate *startDate = //検索対象開始時間
NSDate *endDate = //検索対象終了時間
NSPredicate *predicate = [self.sharedEventKitStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];
NSArray *events = [self.sharedEventKitStore eventsMatchingPredicate:predicate];

for (EKEvent *myEvent in [events reverseObjectEnumerator]) {
    NSError *error = NULL;
    BOOL result = [self.sharedEventKitStore removeEvent:myEvent span:EKSpanThisEvent commit:YES error:&error];
    if (result) {
        //OK
    } else {
        //NG
    }
}

削除はpredicateForEventsWithStartDateを使わずに、MyEventKitを生成した際のidentifierを保持しておけば
EKEventStoreのeventWithIdentifierメソッドの引数にidentifierを渡す事で対象のMyEventKitを取得できるので、そっちのやり方の方が良いかもしれないです。
ちなみにiOS6系からはプライバシー設定の許可を得ている必要があるのでまた別に記入します。