您的位置:首页 > 移动开发

iOS9中如何在日历App中创建一个任意时间之前开始的提醒(一)

2016-03-13 13:18 966 查看

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.

如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)



我们知道如果想在iOS中自带的日历App中创建闹铃开始的时间,这个时间只能从给定几个值中选择一个:



选好完毕后的状态如下:



如果我们有特殊的定时要求该怎么办?比如我们想在日历事件开始前7秒钟订一个闹铃该如何去做?

下面本猫将带大家一起一步一步完成这一功能.

一.获取日历读写许可

首先大家要知道,如果要操作系统日历数据库,我们必须获得对应权限:

EKEventStore *eventStore = [EKEventStore new];
switch ([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]) {
case EKAuthorizationStatusAuthorized:
//我们已经取得了想要的权限
break;
case EKAuthorizationStatusDenied:
[self displayAccessDenied];
break;
case EKAuthorizationStatusNotDetermined:{
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,NSError *error){
if (granted) {
//用户现在许可我们读写日历数据库
}else{
[self displayAccessDenied];
}
}];
break;
}
case EKAuthorizationStatusRestricted:
[self displayAccessRestricted];
break;
default:
break;
}


注意检查许可我们使用的是EKEventStore authorizationStatusForEntityType:类方法,而获取许可我们使用的却是EKEventStore的实例方法requestAccessToEntityType:,这点不要搞混淆.

上面代码中的eventStore实例变量,你可以理解为是日历数据库的抽象.你可能会问为何不用一个单例对象而要new出一个实例变量?一种可能是iOS希望访问日历的方法可以线程安全.

二.找到对应的日历源

接下来我们需要找到特定的日历源,它是EKSource的实例对象.日历源你可以理解为是一些按照日历类型去分类的组.比如在以下模拟器中:



我们可以看到日历数据库共包括了2个日历源,分别是Default和OTHER.你会说第一个源名字不是叫ON MY IPHONE么?你说的Default有时从哪里冒出来的?这个别急,我们会在后面的代码中开到Default名称的由来,你现在只要知道显示在上图中第一个日历源的名称不是真实的名称,它多半是让用户便于理解的而设置的别名.

再举个真机上的例子:



可以看到以上图片是从iPhone6p(iOS9.2.1)拷屏而来的,其中第一个日历源名称为ICLOUD,其中包括了很多日历.我们必须牢记,一台iOS设备(或者Mac设备)上可以有若干个Apple ID,每个Apple ID的日历数据库里可以有若干个日历源,每个日历源里可以有若干个日历.

当然你也可以不通过日历源来枚举日历,你可以直接枚举指定EKEventStore实例中的日历:

NSArray *calendarTypes = @[@"Local",@"CalDAV",@"Exchange",@"Subscription",@"Birthday"];
NSArray *calendars = [store calendarsForEntityType:EKEntityTypeEvent];
NSUInteger i = 1;
for (EKCalendar *calendar in calendars) {
NSLog(@"Calendar %lu Title = %@",(unsigned long)i,calendar.title);
NSLog(@"Calendar %lu Type = %@",(unsigned long)i,calendarTypes[calendar.type]);
NSLog(@"Calendar %lu Color = %@",(unsigned long)i,[UIColor colorWithCGColor:calendar.CGColor]);
if ([calendar allowsContentModifications]) {
NSLog(@"Calendar %lu can be modified.",(unsigned long)i);
}else{
NSLog(@"Calendar %lu cannot be modified.",(unsigned long)i);
}
i++;
}


如果你觉得这样定位日历更快,那么OK!这没问题.不过下面我们来看另一种从指定日历源中枚举日历的方法,下篇再见.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: