之前对这个块也不是很熟悉,然后在一个项目上使用过,所以这里就记下笔记,仅供参考。

准备工作

1.需要在工程中引入EventKit框架,#import <EventKit/EventKit.h>

2.引入了此框架后,我们可以用来操作系统日历和提醒事项,这两个app都是IOS系统自带的功能。

3.这里有个EKEventStore,相当于一个数据库身份。因为使用比较频繁,建议创建成单例模式。

4.添加日历访问权限,IOS10之后需要往info.plist里面配置日历访问权限(NSCalendarsUsageDescription

日历权限检测

//日历权限检测
- (void)checkCalendarAuthorizationCompletion:(void(^)(BOOL granted, NSError *error))completion
{//EKEventStore//检查日历授权状态/*EKAuthorizationStatusNotDetermined = 0, //未进行授权选择EKAuthorizationStatusRestricted, //未授权,且用户无法更新,如家长控制情况下EKAuthorizationStatusDenied, //用户拒绝App使用EKAuthorizationStatusAuthorized, //已授权,可使用*/EKAuthorizationStatus authorizationStatus = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];if (authorizationStatus == EKAuthorizationStatusNotDetermined || authorizationStatus == EKAuthorizationStatusDenied) {//未进行授权选择[[self sharedEKEventStore] requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {if (granted) {DLog(@"授权成功");if (completion) {completion(true,nil);}}else{DLog(@"授权失败,error:%@",error);if (completion) {completion(false,error);}}}];}else if (EKAuthorizationStatusRestricted == authorizationStatus){if (completion) {completion(false,nil);}}else if (EKAuthorizationStatusAuthorized == authorizationStatus){if (completion) {completion(true,nil);}}
}

新增日历事件

//新增日历事件
- (void)addCalendarStartDate:(NSString *)startDate addEndDate:(NSString *)endDate alarms:(NSArray *)alarmArray title:(NSString *)title
{EKEvent *event = [EKEvent eventWithEventStore:[self sharedEKEventStore]];event.title = title;event.startDate = [NSDate dateWithString:startDate formatString:@"YYYY-MM-dd HH:mm:ss"];event.endDate = [NSDate dateWithString:endDate formatString:@"YYYY-MM-dd HH:mm:ss"];// 是否设置全天event.allDay = NO;//添加提醒if (alarmArray && alarmArray.count > 0){for (NSNumber *timeValue in alarmArray) {//如果需要设置提前提醒,需要设置一个负数时间值,单位秒s,根据实际需求转换单位[event addAlarm:[EKAlarm alarmWithRelativeOffset:-1*[timeValue integerValue]*60]];}}//获取日历类型EKCalendar *calendar = [self findEKCalendar:@"根据实际需求新建一个名称即可" eventStore:[self sharedEKEventStore]];[event setCalendar:calendar];// 保存日历NSError *errSave;//EKSpanThisEvent 表示单次日历事件 如果需要保存重复事件需要使用EKSpanFutureEvents//commit 表示当前修改是否要立即提交,因为频繁操作数据库,建议先保存需要添加的事件,最后一把全部提交[[self sharedEKEventStore] saveEvent:event span:EKSpanThisEvent commit:NO error:&errSave];if (errSave) {DLog(@"保存失败,%@",errSave);}else{DLog(@"保存成功");}
}

删除日历事件

// 删除日历事件
- (BOOL)deleteCalendarStartDate:(NSString *)startDate addEndDate:(NSString *)endDate addModifytitle:(NSString *)modifytitle{// 获取到此事件NSArray *request = [self checkToStartDate:startDate addEndDate:endDate addModifytitle:modifytitle];for (int i = 0; i < request.count; i ++) {// 删除这一条事件EKEvent *event = request[i];//获取日历类型EKCalendar *calendar = [self findEKCalendar:@"根据实际需求新建一个名称即可" eventStore:[self sharedEKEventStore]];[event setCalendar:calendar];NSError*error =nil;// commit:NO:最后再一次性提交[[self sharedEKEventStore] removeEvent:event span:EKSpanThisEvent commit:NO error:&error];}//一次提交所有操作到事件库NSError *errored = nil;BOOL commitSuccess= [[self sharedEKEventStore] commit:&errored];if (errored) {DLog(@"删除失败,%@",errored);}else{DLog(@"删除成功");}return commitSuccess;
}

查找日历事件

//查询日历中是否有相同的日历事件
- (NSArray *)checkToStartDate:(NSString *)startDate addEndDate:(NSString *)endDate addModifytitle:modifytitle
{//查询所有的日历NSArray *tempArray = [[self sharedEKEventStore] calendarsForEntityType:EKEntityTypeEvent];NSMutableArray *only3D = [NSMutableArray array];for (int i=0; i<tempArray.count; i++) {EKCalendar *temCalendar = tempArray[i];EKCalendarType type = temCalendar.type;// 工作、家庭和本地日历if (type == EKCalendarTypeLocal || type == EKCalendarTypeCalDAV) {[only3D addObject:temCalendar];}}//谓词查找所有符合条件的日历事件,开始时间-结束时间之内的所有NSPredicate *predicate = [[self sharedEKEventStore] predicateForEventsWithStartDate:[NSDate dateWithString:startDate formatString:@"YYYY-MM-dd HH:mm:ss"] endDate:[NSDate dateWithString:endDate formatString:@"YYYY-MM-dd HH:mm:ss"] calendars:only3D];// 获取到范围内的所有事件NSArray *request = [[self sharedEKEventStore] eventsMatchingPredicate:predicate];request = [request sortedArrayUsingSelector:@selector(compareStartDateWithEvent:)];if (!modifytitle || [modifytitle isEqualToString:@""]) {return request;}else{//日历事件标题筛选NSMutableArray *onlyRequest = [NSMutableArray array];for (int i = 0; i < request.count; i++) {EKEvent *event = request[i];if (event.title && [event.title isEqualToString:modifytitle]) {[onlyRequest addObject:event];}}return onlyRequest;}
}

修改日历事件

这里并没有直接修改日历的接口,所以我们需要变向的达到要求。先做一下删除操作,然后再添加。

- (BOOL)updateCalendarStartDate:(NSString *)startDate addEndDate:(NSString *)endDate addModifytitle:(NSString *)modifytitle
{//1.检测是否有相同的日历事件NSArray *searchResult = [self checkToStartDate:scheduled.startTime addEndDate:scheduled.endTime addModifytitle:scheduled.title];//2.判断该日历事件是否为新增/修改,还是直接删除if (searchResult.count>0) {//1.删除相同日历事件[self deleteCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime addModifytitle:scheduled.title];//2.添加日历事件[self addCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime alarms:@[@(scheduled.scheduleNoticeTime)] title:scheduled.title];}else{//没有相同日历事件,添加日历事件[self addCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime alarms:@[@(scheduled.scheduleNoticeTime)] title:scheduled.title];}return YES;}

完整的写入操作

- (EKEventStore *)sharedEKEventStore
{static EKEventStore *eventStore = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{eventStore = [[EKEventStore alloc] init];});return eventStore;
}- (void)writeScheduledProjectToCalendar:(NSArray <ZDHCScheduledModel*>*)scheduledList
{[self checkCalendarAuthorizationCompletion:^(BOOL granted, NSError *error) {if (granted) {//创建日历EKCalendar *ekCalendar = [self findEKCalendar:@"根据实际需求新建一个名称" eventStore:[self sharedEKEventStore]];if (!ekCalendar) {NSError *err3 = nil;ekCalendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:[self sharedEKEventStore]];ekCalendar.title = @"根据实际需求新建一个名称";ekCalendar.source = [self findEKSourceWitheventStore:[self sharedEKEventStore]];[[self sharedEKEventStore] saveCalendar:ekCalendar commit:YES error:&err3];if (err3) {DLog(@"创建日历失败");}else{DLog(@"创建日历成功");}}[scheduledList enumerateObjectsUsingBlock:^(ZDHCScheduledModel * _Nonnull scheduled, NSUInteger idx, BOOL * _Nonnull stop) {//1.检测是否有相同的日历事件NSArray *searchResult = [self checkToStartDate:scheduled.startTime addEndDate:scheduled.endTime addModifytitle:scheduled.title];//2.判断该日历事件是否为新增/修改,还是直接删除if (scheduled.status) {if (searchResult.count>0) {//1.删除相同日历事件[self deleteCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime addModifytitle:scheduled.title];//2.添加日历事件[self addCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime alarms:@[@(scheduled.scheduleNoticeTime)] title:scheduled.title];}else{//没有相同日历事件,添加日历事件[self addCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime alarms:@[@(scheduled.scheduleNoticeTime)] title:scheduled.title];}}else{if (searchResult.count>0) {//直接删除[self deleteCalendarStartDate:scheduled.startTime addEndDate:scheduled.endTime addModifytitle:scheduled.title];}}}];//最后一把全部提交修改NSError *allUpdateCommitErr;[[self sharedEKEventStore] commit:&allUpdateCommitErr];if (allUpdateCommitErr) {DLog(@"提交完毕报错,:%@",allUpdateCommitErr);}else{DLog(@"提交成功");}}}];}- (EKCalendar*) findEKCalendar:(NSString *)calendarName eventStore: (EKEventStore*)eventStore{NSArray<EKCalendar *> *calendars = [eventStore calendarsForEntityType:EKEntityTypeEvent];if (calendars != nil && calendars.count > 0) {for (EKCalendar *thisCalendar in calendars) {DLog(@"Calendar: %@", thisCalendar.title);if ([thisCalendar.title isEqualToString:calendarName]) {return thisCalendar;}if ([thisCalendar.calendarIdentifier isEqualToString:calendarName]) {return thisCalendar;}}}DLog(@"No match found for calendar with name: %@", calendarName);return nil;
}- (EKSource*) findEKSourceWitheventStore: (EKEventStore*) eventStore{// if iCloud is on, it hides the local calendars, so check for iCloud firstfor (EKSource *source in eventStore.sources) {if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]) {return source;}}// ok, not found.. so it's a local calendarfor (EKSource *source in eventStore.sources) {if (source.sourceType == EKSourceTypeLocal) {return source;}}return nil;
}

到此完美结束。

IOS 往手机日历里增,删,查,该事件提醒相关推荐

  1. 对Android手机系统日历数据增删改查操作详解

    Android手机系统日历数据增删改查详解 前段时间需要开发提取手机系统的日历数据的功能,自己开始研究了一下,刚开始还是比较懵逼的,经过仔细研究还是能够完全贯通了. 如果不想细细研究,可以直接下载我的 ...

  2. 华为手机日历倒计时_华为手机日历怎么设置生日和纪念日提醒?敬业签支持多方式提醒...

    我们在日常生活中除了每天普通的日子外,还有一些对于我们个人来说比较特殊的.有意义的日子,例如亲朋好友的生日.恋爱纪念日.结婚纪念日,以及每月初一十五去上香等.我们将要在一些固定的日期去做指定的事情,如 ...

  3. java 增 删 查 改_如何对java链表进行增、删、查、改操作

    如何对java链表进行增.删.查.改操作 发布时间:2020-06-23 10:41:33 来源:亿速云 阅读:79 作者:Leah 如何对java链表进行增.删.查.改操作?针对这个问题,今天小编总 ...

  4. app如何打开了request url_手机日历app内如何打开节日提醒功能?支持提前提醒节日的云便签...

    我们一年中要度过的节日有很多,除了法定节假日之外,还有其他的很多节日,例如西方传来的圣诞节.万圣节,国际性的节日例如父亲节.母亲节等,还有一些传统节日例如小寒.冬至.腊八等,这些都是不放假的. 有时候 ...

  5. jsp+servlet手机管理(增删改查 二)

    jsp+servlet手机管理(增加和修改二) 在以上篇我们写了实现列表功能 一 :新增功能 注意新增 不仅要增加手机 还要选择手机的品牌 , 我们可以将手机品牌做成下拉列表框 首先 在t_list. ...

  6. iOS使用CNContact对通讯录增删改查

    #import <ContactsUI/ContactsUI.h> 新增联系人 CNMutableContact * contact = [[CNMutableContact alloc] ...

  7. 华为手机日历同步win10日历

    华为手机日历同步win10日历 在网上找了很久资料,终于搞定如何将邮箱与华为日历进行同步了. 很多小伙伴问为什么要同步日历,同步日历有什么好处呢? 首先第一个: **1. 同步日历可以将win10日历 ...

  8. CoreData里的增删改查

    沿着上篇 https://blog.csdn.net/SwiftIOS_watsUp/article/details/100006664 本篇继续讲CoreData,主要是如何在CoreData里增删 ...

  9. 表单的增 删 改 查

    django单表操作 增 删 改 查 一.实现:增.删.改.查 1.获取所有数据显示在页面上 model.Classes.object.all(),拿到数据后,渲染给前端;前端通过for循环的方式,取 ...

最新文章

  1. python 安装库 requirements.txt
  2. ubuntu服务器在虚拟机中的配置
  3. The Moving Points
  4. spring cloud eureka 服务之间调用_Spring-cloud微服务实战【一】:微服务的概念与演进过程...
  5. 函数指针,指针函数,函数指针数组
  6. 哀悼!知名教授逝世,享年55岁!
  7. MOSS中如何自定义WebService
  8. [转载]windows 7 IIS 7.5 ASP.Net 文件上传大小限制
  9. NGUI学习笔记汇总
  10. 用oracle的sqlload导入文件到数据库
  11. Python编程语言入门视频教程,人生苦短,我用Python!
  12. Modelica技术特点及优势
  13. android 禁止第三方相机,谷歌突然宣布,Android 11推出新规,第三方相机软件猝不及防...
  14. 所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。本题要求构造这样的螺旋方阵。
  15. 糅合不好变搀合,搀合不好变搅合
  16. Excel学习日记:L23-如何计算成绩排名
  17. python添加文字水印中间旋转45度,Python添加pdf水印
  18. 589. N 叉树的前序遍历(javascript)589. N-ary Tree Preorder Traversal
  19. 关闭计算机防火墙命令,win10系统关闭防火墙命令执行的设置方案
  20. 安卓手机”应用未安装“解决办法

热门文章

  1. 再读内核存储管理(7):icache支持
  2. 微信支付宝H5收款码扫码转账个人通道,灵活配置,仿原生接口,带备注可回调成功率9成以上
  3. 微信小程序 实现css样式搭建(如三角形、正方形、圆形等)
  4. python实现微信抢红包神器_快过年啦,还怕手速慢,我用Python自动抢红包!
  5. textmate 主题_Stylelint + TextMate集成
  6. 选择困难症__牛客网
  7. 还在人工巡检?配电室这5大目标确定了
  8. ios Rn0.44 Xcode9 ScrollView下拉距离过短或下拉刷新后 不能自动回弹、复位置顶
  9. rf 's book
  10. 我的第二故乡 – 成都 I