2013年3月18日 星期一

Event Kit Framework 匯入iOS行事曆

[轉自http://iosdevelopersnote.blogspot.tw/2010/09/ios-event-kit-framework.html] iOS 4.0 可以充許開發者去存取存iPhone裡的行事曆, 和通訊錄相同的行事曆的整個是用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( CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(), timeZone, startUnits), 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

沒有留言:

張貼留言