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

Posted 大熊猫侯佩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS9中如何在日历App中创建一个任意时间之前开始的提醒相关的知识,希望对你有一定的参考价值。

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! 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!这没问题.不过下面我们来看另一种从指定日历源中枚举日历的方法,下篇再见.



以上是关于iOS9中如何在日历App中创建一个任意时间之前开始的提醒的主要内容,如果未能解决你的问题,请参考以下文章

iOS9中怎样在日历App中创建一个随意时间之前開始的提醒

iOS日历中给一个事件添加多个提醒

如何在 iPhone 应用程序中创建日历?

如何在 React Native 中创建自定义日历?

如何使用swift2在ios9中创建jabberd xmpp客户端

如何在 ASP.net Core 中创建日历日期/选择器?