和通訊錄相同的行事曆的整個是用Core Foundation架構起來的是C 而不是Objective-C
Core Foundation是C, Foundation是Objective-C
但是兩者之間有很方便的轉換方法,其實就是直接cast,這個又叫做Toll-Free bridge
比如CFStringRef和NSString *要轉換就直接寫
CFStringRef cfString = xxxxxx;
NSString * objString = (NSString *) cfString;
這樣就可以直接用objString來當成cfString的替身了
先介紹一下幾個重要的c structure在event kit 會用到的
CFGregorianDate : 標準的日曆表示法,含有年,月,日,時,分,秒。至於為什麼叫Gregorian 請參考
CFGregorianUnits : 表示一段時間,和CFGregorianDate有相同的結構,但沒有限制值的範圍。比如說在CFGregorianDate"時"的值不能超過24小時,但在CFGregorianUnits"時"的值就可以超過24小時,因為它代表的是一段時間
我們來直接來看一個按下去按鈕就新增自訂event的例子
-(IBAction) createEvent:(id)sender{
NSLog(@"launched");
EKEventStore * myEventStore = [[EKEventStore alloc] init];
EKEvent * myEvent = [EKEvent eventWithEventStore:myEventStore];
myEvent.title = @"Knowledage Convergence Meeting";
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {0, 0, 0, 1, 3, 0};
CFGregorianUnits endUnits = {0, 0, 0, 1, 5, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();
gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeGetCurrent(), timeZone);
gregorianStartDate.hour = 17;
gregorianStartDate.minute = 55;
gregorianStartDate.second = 10;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, endUnits),
timeZone);
gregorianEndDate.hour = 17;
gregorianEndDate.minute = 55;
gregorianEndDate.second = 25;
NSDate* startDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate = [NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
myEvent.startDate = startDate;
myEvent.endDate = endDate;
myEvent.calendar = [myEventStore defaultCalendarForNewEvents];
EKAlarm *myAlarm = [EKAlarm alarmWithAbsoluteDate:startDate];
myEvent.alarms = [NSArray arrayWithObject:myAlarm];
NSError *theError = nil;
[myEventStore saveEvent:myEvent span:EKSpanThisEvent error:&theError];
NSLog(@"error is %@", theError);
}
這個流程主要就是產生自己的EKEvent, 藍色的property都是必要的,除了alarms之外,EKEvent又必需要和 EKEventStore結合,因為event實體是EKEventStore給的,event裡的calendar也是EKEventStore給的,而EKEventStore實體的產生就只是用alloc, init方式。
其中最麻煩的就是startDate和endDate,輾轉要從 CFGregorianDate 或是 CFGregorianUnits而來
單看是要從 CFAbsoluteTimeGetGregorianDate產生還是要從 CFAbsoluteTimeAddGregorianUnits產生,不過記得一點,產生 CFGregorianDate 的實體之後可以從他的field,year, month, day, hour, minute, second 來設定絕對的時間就如墨綠色部分所示。
EKAlarm 可有可無,它是先和NSDate結合,再一起被設定到EKEvent