EventKit框架提供了一种访问存储在日历数据库(Calendar Database)的日历、日历事件、提醒数据的方式。iOS4开始就支持访问日历和日历事件、而iOS6起增加支持访问提醒
EventKit的使用方法
在info.plist添加Privacy - Calendars Usage Description
,允许用户访问日历。
因为EventKit的核心EventStore很像一个数据库引擎,所以他应该长久持有,这意味着在应用的生命周期内它应该尽可能的少创建、销毁。实际,建议这样:一旦你在应用中创建了一个EventStore,你应该在应用的生命周期内保持它(EventStore)的引用,除非你确定你再不使用它了。另外,所有的调用都针对鱼一个EventStore实例。所以呢,推荐单例模式。
#import "EventEngine.h"
@interface EventEngine ()
@property (nonatomic, strong) EKEventStore *eventStore;
@end
@implementation EventEngine
static EventEngine *_instance;
+ (instancetype)engine{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[EventEngine alloc] init];
if (_instance.eventStore == nil) {
_instance.eventStore = [[EKEventStore alloc] init];
}
});
return _instance;
}
日历授权
//授权
- (void)authority{
if ([self.eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"用户授权错误");
}else if (!granted){
//这里是用户拒绝授权的返回,这个方法应该给一个block回掉,来更具用户授权状态来处理不同的操作,我这里为方便直接写个跳转到系统设置页
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}else{
NSLog(@"用户授权成功");
}
});
}];
}
}
接下来就可以用_eventStore
来操作日历的增删改查了
//获取所有的日历
- (NSArray *)getCalendar{
return [_eventStore calendarsForEntityType:EKEntityTypeEvent];
}
新建日历
//创建一个日历
- (void)creatCalendarWithTitle:(NSString *)title color:(UIColor *)color{
for (EKCalendar *calendar in [_eventStore calendarsForEntityType:EKEntityTypeEvent]) {
if ([calendar.title isEqualToString:title] ) {
NSLog(@"已经存在这个日历了");
}
}
EKSource *localSource = nil;
#if TARGET_IPHONE_SIMULATOR//真机
for (EKSource *source in _eventStore.sources){
//获取iCloud源
if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]){
localSource = source;
break;
}
}
#else//模拟器
for (EKSource *source in _eventStore.sources) {
//获取本地Local源(就是上面说的模拟器中名为的Default的日历源)
if (source.sourceType == EKSourceTypeLocal){
localSource = source;
break;
}
}
#endif
EKCalendar *calendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:_eventStore];
calendar.source = localSource;
calendar.title = title;//自定义日历标题
calendar.CGColor = color.CGColor;//自定义日历颜色
NSError* error;
[_eventStore saveCalendar:calendar commit:YES error:&error];
}
05F18449-1E05-4C9A-8149-AD505ABFAAD7.png
EKCalendar的属性
title
:NSString,就是日历的标题
type
:EKCalendarType对应日历app的几种类型
一共有5种类型
EKCalendarTypeLocal,//使用模拟器使用
EKCalendarTypeCalDAV,//iCloud,真机一般使用这个
EKCalendarTypeExchange,//这个应该是能使用其他操作,比如邮件,Siri,对应截图中的Siri found in Apps
EKCalendarTypeSubscription,//带标题,对应截图中的US Holidays
EKCalendarTypeBirthday//对应截图中的生日
color
:这个是日历名称旁边的圆圈颜色
source
:可以理解为是按照日历类型去分类的一些组
获取一段事件之内的事件
// 获取一个时间段的所有事件
- (NSArray *)getEventsFromDate:(NSDate *)startDate toDate:(NSDate *)endDate calendarTitles:(NSArray <NSString *>*)titles{
NSMutableArray *calendarArray = [NSMutableArray array];
for (int i = 0; i < titles.count; i ++) {
for (EKCalendar *calendar in [_eventStore calendarsForEntityType:EKEntityTypeEvent]) {
if ([calendar.title isEqualToString:titles[i]] ) {
[calendarArray addObject:calendar];
}
}
}
NSPredicate *predicate = [_eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:calendarArray];
//同步执行,代码需优化
return [_eventStore eventsMatchingPredicate:predicate];
}
创建一个事件
//创建一个事件
- (void)creatEventWithTitle:(NSString *)title startDate:(NSDate *)startDate endDate:(NSDate *)endDate{
EKEvent *event = [EKEvent eventWithEventStore:_eventStore];
event.title = title;
//设定事件开始时间
event.startDate = startDate;
//设定事件结束时间
event.endDate=endDate;
//给事件添加闹钟
EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:-5.f];
// alarm的soundName和type属性在iOS系统中不可用
[event addAlarm:alarm];
[event setCalendar:[_eventStore defaultCalendarForNewEvents]];
NSError *error;
[_eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&error];
}
网友评论