由於想要提早推播通知朋友生日,我必須取得取得行事曆的事件 (Get Event From Calendar)。
實際上我想知道資料回傳格式,如此能讓設計師規劃介面。
老實說,我沒在用內建的行事曆App,行事曆中的生日資料,是老早之前登入臉書帳號後,系統擷取回來加入。
因為行事曆涉及個人隱私,必須得到用戶的授權,才能順利取得!而且開發者必須提示為何要取用行事曆,不然App崩潰給你看~
直接參照前人的教學,一個完整程式流程即能順利取得「生日事件」!
/** Theme: 取得行事曆的事件 (Get Event From Calendar) IDE: Xcode 11 Language: Objective C Date: 108/05/26 Author: HappyMan Blog: https://cg2010studio.com/ */ -(void)getEventsFromCalendar { EKEventStore *eventStore = [[EKEventStore alloc] init]; EKSource *localSource = nil; for (EKSource *source in eventStore.sources){ // 獲取iCloud源。這裡可以只通過日曆源的title來查找,不過加上對類型的檢查就是雙保險 if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]){ // 把获取到的iCloud源保存起来 localSource = source; } } EKCalendar *birthdayCalendar; for (EKCalendar *ekcalendar in [eventStore calendarsForEntityType:EKEntityTypeEvent]) { // 當然這裡也可以加上日曆源類型的檢查,像上面一樣的雙保險 calendar.type == EKCalendarTypeCalDAV if ([ekcalendar.title containsString:@"Birthday"] ) { birthdayCalendar = ekcalendar; } } NSCalendar *calendar = [NSCalendar currentCalendar]; // 建立起始日期 NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init]; oneDayAgoComponents.day = -1; NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents toDate:[NSDate date] options:0]; // 建立結束日期 NSDateComponents *oneMonthFromNowComponents = [[NSDateComponents alloc] init]; oneMonthFromNowComponents.month = 2; NSDate *oneMonthFromNow = [calendar dateByAddingComponents:oneMonthFromNowComponents toDate:[NSDate date] options:0]; // 用事件庫的實例方法創建謂詞。表示 找出從當前時間前一天到當前時間的二個月後的時間範圍的所有typesArray裡類型的日曆事件 NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:oneDayAgo endDate:oneMonthFromNow calendars:@[birthdayCalendar]]; NSArray *eventArray = [eventStore eventsMatchingPredicate:predicate]; }
接著實機測試,看能從我手機中獲得什麼樣的資料~
EKEvent <0x28358a5b0>
{
EKEvent <0x28358a5b0>
{ title = Mickey Chiang’s 30th Birthday;
location = (null);
calendar = EKCalendar <0x281d9c3c0> {title = Birthdays; type = Birthday; allowsModify = NO; color = #8295af;};
alarms = (null);
URL = (null);
lastModified = (null);
startTimeZone = (null);
startTimeZone = (null)
};
location = (null);
structuredLocation = (null);
startDate = 2020-06-04 16:00:00 +0000;
endDate = 2020-06-05 15:59:59 +0000;
allDay = 1;
floating = 1;
recurrence = EKRecurrenceRule <0x28249d360> RRULE FREQ=YEARLY;INTERVAL=1;
attendees = (null);
travelTime = (null);
startLocation = (null);
};,
看來只有Title和startDate或endDate最為基本可得!
另外,行事曆中有分別「日曆」的來源:
EKSource <0x28025c310> {UUID = 235223D6-26EC-40D6-AAA4-6E1F2BD2FE13; type = Subcribed; title = Subscribed Calendars; externalID = Subscribed Calendars}
Printing description of source:
EKSource <0x28025c3f0> {UUID = 16DCE4F6-6D04-4B74-A897-21E1093C2B13; type = CalDAV; title = iCloud; externalID = 16DCE4F6-6D04-4B74-A897-21E1093C2B13}
Printing description of source:
EKSource <0x28025c4d0> {UUID = BE47681A-4986-4363-B809-B0A576B336D2; type = Other; title = Other; externalID = (null)}
篩選出我們要的即可~
隨意留個言吧:)~