文章目录

最近在公司的项目开发过程中遇到一个需求:获取系统日历内的事件,通过 ANCS 协议通知可穿戴设备,所以就找了官方的Demo看了一下。

首先,日历中所以的事件都是通过EKEventStore这个类来管理的,所有单独的事件都是一个个EKEvent对象,结合下面的数据和日历事件详情截图可获取对应的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	 EKEvent <0x125d53960>
{ title = EventKit介绍;
location = 深圳宝安国际机场
机场南路;
calendar = EKCalendar <0x125f99cc0> {title = 家庭; type = CalDAV; allowsModify = YES; color = #FFCC00;};
alarms = (
"EKAlarm <0x1270fa720> {triggerInterval = -54000.000000}",
"EKAlarm <0x1270b5f10> {triggerInterval = -140400.000000}"
);
URL = www.google.com;
lastModified = 2016-01-14 10:58:18 +0000;
startTimeZone = (null);
startTimeZone = (null)
};
location = 深圳宝安国际机场
机场南路;
structuredLocation = EKStructuredLocation <0x1270b3f30> {title = 深圳宝安国际机场; address = 机场南路; geo = <+22.62538000,+113.81286600> +/- 0.00m (speed -1.00 mps / course -1.00) @ 16/1/14 中国标准时间 19:01:31; abID = (null); routing = (null); radius = 14194.038856;};
startDate = 2016-01-13 16:00:00 +0000;
endDate = 2016-01-16 15:59:59 +0000;
allDay = 1;
floating = 1;
recurrence = EKRecurrenceRule <0x125da27f0> RRULE FREQ=DAILY;INTERVAL=1;UNTIL=20160315T235959Z;
attendees = (
"EKAttendee <0x1270cf2b0> {UUID = 28FB4329-77A5-4206-B7CA-30AC42AC25EC; name = 李四; email = lisi@gmail.com; status = 0; role = 0; type = 1}",
"EKAttendee <0x1270cf300> {UUID = DBFE4217-DEDC-4527-BC73-09938F3789BD; name = 张三; email = zhangsan@gmail.com; status = 2; role = 0; type = 1}"
);
travelTime = (null);
startLocation = (null);
};

EventKit.framework相对是比较简单的,但还是有几点需要弄清楚:

  • 事件中带的提醒功能是EKAlarm对象,提醒中设置的提前提醒时间是根据relativeOffset这个属性来获取,这是一个NSTimeInterval数据,数值表示距离该事件起始时间有多少秒。相关详情可查阅EKAlarm Class Reference
  • 事件中的定位信息的类是EKStructuredLocation,相关详情可查阅EKStructuredLocation Class Reference
  • 循环规则的类是EKRecurrenceRule,需要注意的是在RRULE FREQ=DAILY;INTERVAL=1;UNTIL=20160315T235959Z;RRULE FREQ=DAILY表示是每天循环,也有WEEK等可供选择,INTERVAL=1表示是循环间隔是1天,如果2则表示隔一天循环一次。UNTIL=20160315T235959Z表示循环结束时间是2016年03月15日 23:59:59。相关类详情可查阅EKRecurrenceRule Class Reference
  • 被邀请人的类是EKParticipant,里面有姓名,E-mail等数据,相关详情可查阅EKParticipant Class Reference

下面直接上代码:

  1. 检查日历授权
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#pragma mark - 检查日历授权
- (void)checkEventStoreAccessForCalendar {
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];

switch (status)
{
// Update our UI if the user has granted access to their Calendar
case EKAuthorizationStatusAuthorized: [self fetchEvents];
break;
// Prompt the user for access to Calendar if there is no definitive answer
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
// Display a message if the user has denied or restricted access to Calendar
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:kLStr(@"Matters Reminder")
message:kLStr(@"RemindersAlertMsg")
delegate:self
cancelButtonTitle:kLStr(@"Alert Cancel")
otherButtonTitles:kLStr(@"Alert Setting"), nil];
[alertView show];
}
break;
default:
break;
}
}
  1. 授权App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma mark - 授权app访问日历数据
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
__weak typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf fetchEvents];
});
}
}];
}
  1. 获取日期范围内的日历数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (NSMutableArray *)fetchEvents
{
NSDate *startDate = [NSDate date];
NSDate *endDate = [NSDate date];
NSDateComponents *tomorrowDateComponents = [[NSDateComponents alloc] init];
//往后365天数据
tomorrowDateComponents.day = 365;
endDate = [[NSCalendar currentCalendar] dateByAddingComponents:tomorrowDateComponents
toDate:endDate
options:NSCalendarSearchBackwards];
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:nil];
NSMutableArray *events = [NSMutableArray arrayWithArray:[self.eventStore eventsMatchingPredicate:predicate]];
return events;
}
  1. 跳转原生日历界面
1
2
3
4
5
6
7
- (void)jumpIntoEvent{
EKEventViewController* eventViewController = [[EKEventViewController alloc] init];
//此处应传入一个EKEvent对象
eventViewController.event = self.dataSource[0];
// Allow event editing
eventViewController.allowsEditing = YES;
}
文章目录