iOS日历相关操作--读取系统日历、添加事件到系统日历

1 读取系统日历

        let eventStore = EKEventStore()

        let tempFormatter = NSDateFormatter()
        tempFormatter.dateFormat = "dd.MM.yyyy HH:mm"

        //获取一个时间段中的日历事件
        let startDate = tempFormatter.dateFromString("10.08.2016 15:10")!
        let endDate = tempFormatter.dateFromString("12.08.2016 15:30")!

        let predicate = eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: [eventStore.defaultCalendarForNewEvents])

        //获取这个时间段中的所有日程
        let events = eventStore.eventsMatchingPredicate(predicate)

2 添加事件到系统日历

     let eventStore = EKEventStore()
        eventStore.requestAccessToEntityType(.Event) { (granted, error) in

            dispatch_async(dispatch_get_main_queue(), { 

                if error != nil {
                    //发生错误
                } else if !granted {
                    //不允许访问日历
                } else {

                    //创建事件
                    let event = EKEvent(eventStore: eventStore)
                    event.title = "lallallallal"

                    let tempFormatter = NSDateFormatter()
                    tempFormatter.dateFormat = "dd.MM.yyyy HH:mm"

                    //创建一个时间段的日历事件
                    event.startDate = tempFormatter.dateFromString("11.08.2016 15:20")!
                    event.endDate = tempFormatter.dateFromString("11.08.2016 15:30")!

                    //设置是否为全天事件
                    event.allDay = false

                    //设置事件的提醒时间(相对时间)提前15分钟提醒
                    event.addAlarm(EKAlarm(relativeOffset: -60.0 * 15.0))
                    //设置事件的提醒时间(绝对时间)
                    //event.addAlarm(EKAlarm(absoluteDate: NSDate(timeInterval: -60 * 15, sinceDate: event.startDate)))

                    event.calendar = eventStore.defaultCalendarForNewEvents

                    //保存事件,添加到日历中
                    do {
                        try eventStore.saveEvent(event, span: .ThisEvent, commit: true)
                    } catch {

                    }
                }

            })
        }

3 分析:

  日历分为两类,一类用于存储事件的日历,一类用于存储提醒的日历。

  EventKit库框架授权访问用户的日历app及提醒事项app。尽管是用两个不同的应用来显示用户的日历和提醒数据,但却是同一个框架来维护这份数据。同样地,存储这份数据的数据库叫做日历数据库,同时容纳日历和提醒信息。

  事件库不但允许你的应用获取用户已经存在的日历及提醒数据,而且它可以让你的应用为任何日历创建新的事件和提醒。另外,事件库让用户可以编辑和删除他们的事件和提醒(整体叫做“日历项”)。如果日历数据库有来自你的应用外部的更改发生,事件库可以通过通知监测到,这样你的应用可以做出适当的响应。使用事件库对日历项所做的更改会自动地同步到相关的日历。

(1)读写日历数据库

  你可以使用 EKEventStore 类从用户的日历数据库中获取、创建、编辑和删除事件。你可以获取匹配你提供的谓词的事件自定义的一组事件,或通过唯一标识获取一个单独的事件。你获取到一个事件后,可以使用 EKEvent 类的属性获取访问该事件相关的日历信息。同样的,你可以通过设置 EKEvent 类的属性来修改该事件的日历信息。 

  • 连接到事件库
    在 iOS 5 及以后版本系统中,使用默认的初始化器:

    let eventStore = EKEventStore()

    在 iOS 6 及以后版本,你必须在事件库初始化后,使用 requestAccessToEntityType:completion: 方法请求使用用户的日历数据库。请求访问某个实体类型会异步提示用户允许或禁止你的应用使用他们的日历信息。你应该处理用户授权或禁止你的应用访问权的各种状况:

    eventStore.requestAccessToEntityType(.Event) { (granted, error) in
    
    }

    EKEventStore 对象需要相对较大量的时间来初始化和释放。因此,你不应该为每一个事件相关的任务都初始化和释放事件库。相反,在你的应用加载时,初始化一个事件库,然后反复地使用这一个来确保连接一直可用。事件库实例不应该在其它事件开发包相对的对象释放前被释放,否则可能发生意想不到的状态。

  • 获取事件
    有两种方式获取事件。通过谓词或搜索查询获取,会返回零个或多个与给定查询匹配的事件。通过唯一标识获取会返回与给定标识相符的唯一的一个事件。
    注意:从日历数据库获取事件并不一定按时间顺序返回。要通过日期排序 EKEvent 对象的数组,可以在数组上调用 sortedArrayUsingSelector: 方法,并提供  compareStartDateWithEvent: 方法的选择器。
  • 使用谓词
    通常是要获得属于某一日期范围的事件。 EKEventStore 的 eventsMatchingPredicate: 方法获取属于你提供的谓词中指定的日期范围的所有事件。
    注意:尽管  eventsMatchingPredicate: 方法接受一个 NSPredicate类型的参数,但你必须提供一个用 EKEventStore 的方法 predicateForEventsWithStartDate:endDate:calendars: 创建的谓词。
    你可以指定一个日历的子集来搜索,这需要传递一个 EKCalendar 对象的数组作为 predicateForEventsWithStartDate:endDate:calendars: 方法的 calendars 参数。你可以从事件库的 calendarsForEntityType: 方法获得用户的不同类型的日历。如果传一个 nil 值,那么就是告诉这个方法获取用户的所有日历。
    因为方法  eventsMatchingPredicate: 是同步的,而你可能并不想在你的应用主线程中运行它。如果要异步执行的话,那么使用 dispatch_async 函数或使用一个 NSOperation 对象,就可以在另一个线程中运行该方法了。
  • 使用唯一标识
    如果你之前使用谓词获得了一个事件并知道它的唯一标识,那么你可以使用 EKEventStore 的 eventWithIdentifier: 方法来再次获取该事件。如果它是一个循环事件,那么这个方法就会返回第一次出现的该事件。你可以使用属性 eventIdentifier 获得事件的唯一标识。
  • 创建及编辑事件
    使用 事件 EKEvent 的eventWithEventStore: 方法创建一个新的事件。
  • 保存和移除事件

    提示:如果你的应用修改用户的日历数据库,它必须在这之前先从用户获得确认。应用在未得到用户的特定指示的情况下决不可能修改日历数据库。

    你对事件的修改不是持久化的,直到你保存它们为止。使用 EKEventStore 的 saveEvent:span:commit:error: 方法保存你的修改到日历数据库中。如果你要从日历数据库移除事件,使用 EKEventStore 的 removeEvent:span:commit:error: 方法。无论你保存或移除事件,各自实现的方法都会自动所做的修改到该事件所属于的日历(CalDav、Exchange等等)。

    如果你保存一个循环事件,你可以通过给 saveEvent:span:commit:error: 方法的参数 span 指定 EKSpanFutureEvents 来使你的更改应用到所有未来出现的该事件中。同样地,你也可以指定 removeEvent:span:commit:error: 方法的 span 参数值为 EKSpanFutureEvents 来移除一个事件的所有未来的出现。

    注意:如果你给 commit 参数传了 NO 值,那么要确保稍侯调用 commit: 方法以持久保存你的更改(译者注:默认传 YES 会立即持久保存更改)。

参考链接:http://www.cnblogs.com/xiaobaichangan/p/5160025.html

时间: 2024-10-12 20:11:37

iOS日历相关操作--读取系统日历、添加事件到系统日历的相关文章

Android 向系统日历中添加事件

查了一天半,总算有点大概了.以下是自己的理解,有错误的地方望指正. android系统有日历功能,应用程序可以根据一些接口开发自己的功能,即使是日历app也是根据这些接口开发的,所以我们可以利用程序向系统日历写入事件,然后用手机上的日历软件就可以看到我们添加的事件.网上这方面资料也不少,也有demo,但是我没找到一个可以正确运行的,有的是缺少参数,有的是版本的原因,4.0以上的系统这方面变动比较大,所以只能一边查资料一边修改. 大体思路就是:先查看系统日历是否有账户,如果没有必须要添加一个,然后

javascript动手写日历组件(2)——优化UI和添加交互(by vczero)

一.优化UI 继上一篇,http://www.cnblogs.com/vczero/p/js_ui_1.html.开始优化UI,主要优化的部分有: (1)增加星期行.(2)字体设置.(3)日期垂直居中.(4)将单元格->底部线条.(5)修改文本的颜色对比.(6)将内部调用的函数加前缀_,如_addHeader()._addWeekday(). 修改的后基本效果如下图: 整个代码做了小修小改: 1 var Calendar = function(div){ 2 this.div = documen

yii 数据库添加,修改,删除相关操作总结

yii中关于数据信息的添加数据,修改数据,删除数据的相关操作,刚刚学习没几天,仅记录了一些,以后慢慢再充实,有需要的朋友可以看看. 添加数据的方法 (1)save 方法(对象形式操作) $user=new User;$user->username='phpernote';$user->password='123456';if($user->save()>0){    echo '添加成功';}else{    echo '添加失败';} (2)insert 方法(数组形式操作) Y

AE开发中对GDB以及shapefile的读取、对FeatureClass的相关操作

读取gdb方法 private void btn_Click(object sender, EventArgs e) { FolderBrowserDialog dlg = new FolderBrowserDialog(); dlg.Description = "打开GDB文件夹"; if (DialogResult.OK == dlg.ShowDialog()) { if (Directory.Exists(dlg.SelectedPath)) { if(dlg.SelectedP

linux下进程相关操作

一.定义和理解 狭义定义:进程是正在运行的程序的实例. 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动. 进程的概念主要有两点: 第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域.数据区域和堆栈区域.文本区域存储处理器执行的代码:数据区域存储变量和进程执行期间使用的动态分配的内存:堆栈区域存储着活动过程调用的指令和本地变量. 第二,进程是一个“执行中的程序”.程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们

IOS之文件操作

Project Day02 文件的相关操作 NSFileManger:对整个文件进行操作<手机文件在沙箱中不能直接操作>   删除文件 步骤: 1 创建NSFileManger的实例 2. 创建NSerror的实例初始值为空 3. 调用removeItemAtPath方法第一个参数为要删除的文件的位置第二个error的参数设置为&error的地址 4. 错误判断 如果出错 可以调用[error  localizedDescription]返回系统提供给的描述 NSFileManager

[编写高质量iOS代码的52个有效方法](十一)系统框架

[编写高质量iOS代码的52个有效方法](十一)系统框架 参考书籍:<Effective Objective-C 2.0> [英] Matt Galloway 先睹为快 47.熟悉系统框架 48.多用块枚举,少用for循环 49.对自定义其内存管理语义的容器使用无缝桥接 50.构建缓存时选用NSCache而非NSDictionary 51.精简initialize与load的实现代码 52.别忘了NSTimer会保留其目标对象 目录 编写高质量iOS代码的52个有效方法十一系统框架 先睹为快

(二十四)linux新定时器:timefd及相关操作函数

timerfd是Linux为用户程序提供的一个定时器接口.这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景. 一,相关操作函数 #include <sys/timerfd.h> int timerfd_create(int clockid, int flags); int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itim

python文件相关操作

Python文件相关操作 打开文件 打开文件,采用open方法,会将文件的句柄返回,如下: f = open('test_file.txt','r',encoding='utf-8') 在上面的代码中,open()方法进行打开文件等相关操作,open()方法其中第一个参数是要打开的文件的文件路径,第二个参数是对要打开文件要执行的权限,第三个参数是文件采用字符编码. 而open()方法返回的内容叫做文件句柄.我们可以打印返回的文件句柄来看下: f = open('test_file.txt','r