Swift EventKit的初学者指南–请求权限
EventKit为获取和操作用户日历事件和提醒提供了一系列的类.在下面的教程中,我的目标是带领你走出利用EventKit建立一个应用程序的第.我的目标是带领你迈出利用EventKit建立一个应用程序的第一步.我将演示如何向用户的日历请求许可,我还将展示几个处理用户响应的例子(当他们授予访问权限,或者拒绝).
Example scenario
场景
让我们先提出一个基本方案,作为本教程的例子。
假设我们正在构建一个应用程序,现在,有一个单一的视图控制器。在得到用户授权允许的情况下,我们希望这个视图控制器显示日历列表。如果用户拒绝访问,我们将向用户展示一个消息,用来说明我们的应用程序在没有访问权限时不能运行,我们也将允许他们通过单击一个按钮能够在他们的设备的设置中设置授权访问.
我已经创建一个那样的应用程序作为例子–跳到GitHub中查看并研究这个例子的代码.
资源
Storyboard setup
故事面板设置
你使用EventKit的第一步就是需要为自己创建一个用户界面来处理当你第一个程序启动时用户对”该程序可以访问你的日历吗?”对出不同的响应,不久,我们将得到如何请求这个许可的详情.但首先,让我们来剖析我们如何用对于一个许可操作导致的给定响应能够做正确的操作的一些视图来安排我们的故事板.
用户可以授予访问权限,也可以拒绝授予访问权限来通知他们的日历或者提醒.我们需要为这两种情况做好准备.
当被授予访问权限时,tableview显示日历列表
我今天持乐观态度,所以让我们开始处理从一开始用户就授予我们访问他们日历的权限的情况.
当用户授予我们访问权限,我们想列出一个表视图的日历.在接下来的教程中,我们将担心数据源的设置.现在,我们将从实用工具栏中拽一个表格视图过来.
为了得到填满整个屏幕的表视图,我做了几件事情.通常,当你从实用工具栏中拽一个表视图过来的时候,它会在故事板中填满整个场景.在布局中我向下拖顶部边缘知道它”捕捉”到我所期望的状态栏底部被定位的那行.然后,我设置了以下限制:
Center X
Center Y
Equal width to Superview
Top space to Top Layout Guide for height.
我已经创建了一个设置表视图的简短截屏,如果你想要一个完整的练习,可以参看下面链接的内容:
Resources
资源
这里有这些约束的详细视图,以及故事板看起来像装表视图的视觉效果.


最后一点,在故事板中我已经将这个表视图的hidden属性设置为true.根据用户允许或者拒绝对日历的访问后,我将切换表的可见性,但我认为值得指出的是在我例子中表视图的初始状态是被隐藏.
访问被拒绝时的”需要许可”视图
但有时,用户拒绝授权访问日历,在意识到这样做将导致基本上停止你应用程序所有的功能之前,如果你的整个应用程序或者只是该应用程序的一部分需要访问功能,你需要一种方法来告知用户,并为他们提供一种方法跳到用户设置,如果可能的话让用户手动授予访问权限.
我在示例项目中的方法是在故事板场景中组织一个新的视图,该视图包含一个展示操作说明的标签和一个点击后使用户进入我们应用程序的设置界面的按钮.
再次,一些约束涉及到在运行时使一些事物正确的显示.在这里我不会讲述这个细节,因为它很可能因为每一个执行操作而有一点不同.
我将指出的意见事情是,这个视图的透明度已经被设置为0,以便如果用户拒绝授权,我能够展示一个逐渐消失的效果.下面就来看看在设置了隐藏“NeedPermissionsView”的场景:

Event Store的角色
EventKit的核心是EKEventStore.EKEventStore是事物的中心.创建EKEventStore的一个实例,为开发人员提供了对用户的日历和提醒列表中执行各种读/写操作的API.
一个与日历交互的视图控制器应该有一个引用EKEventStore的实例.这很容易被创建–这里是一个例子:
ViewController.swift
|
1
2
3
4
|
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {let eventStore = EKEventStore()// ...} |
检查日历的授权
一旦我们有了引用EKEventStore的实例,我们可以做像检查用户是否授权访问他们的日历这样的事情.根据这里,我们可以做是否需要请求许可的决定,随后确定要显示的视图(表视图或者需要许可视图).
我们在哪里检查日历授权很重要.我的建议是每次在视图出现时检查(即在viewWillAppear()中),因为用户首次授予访问权限,切换设置,拒绝访问的情况是完全有可能的.我们的应用程序需要做出适当的响应.
In the example project provided with this article, I’ve created a function named checkCalendarAuthorizationStatus(). Here a peek at what it does:
在这个文章提供的示例工程中,我已经创建了一个名为checkCalendarAuthorizationStatus()的函数.
接下来看看它的实现:
ViewController.swift
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { // ... override func viewWillAppear(animated: Bool) { checkCalendarAuthorizationStatus() } func checkCalendarAuthorizationStatus() { let status = EKEventStore.authorizationStatusForEntityType(EKEntityTypeEvent) switch (status) { case EKAuthorizationStatus.NotDetermined: // This happens on first-run requestAccessToCalendar() case EKAuthorizationStatus.Authorized: // Things are in line with being able to show the calendars in the table view loadCalendars() refreshTableView() case EKAuthorizationStatus.Restricted, EKAuthorizationStatus.Denied: // We need to help them give us permission needPermissionView.fadeIn() default: let alert = UIAlertView(title: "Privacy Warning", message: "You have not granted permission for this app to access your Calendar", delegate: nil, cancelButtonTitle: "OK") alert.show() } } // ...} |
这里关键的功能是EKEventStore的 authorizationStatusForEntityType实现的.传入的EKEntityTypeEvent用于跟用户日历进行交互.如果我们想要检查他们的提醒的权限,我们将在这里使用EKEntityTypeReminder.
EKAuthorizationStatus的可能值根据switch里的相应的case来执行封装好的方便阅读的独立功能的逻辑代码.
让我们一步步来看一看这些功能.
请求访问日历
正如标题所说的,所有的事情从这里开始.每当我们的应用程序加载和调用authorizationStatusForEntityType的时候,将返回NotDetermined的状态.就是在这一点上我们想请求访问日历.
为了这样做,按照下面的方法定义requestAccessToCalendar函数:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
requestAccessToCalendar()class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {// …func requestAccessToCalendar() {eventStore.requestAccessToEntityType(EKEntityTypeEvent, completion: {(accessGranted: Bool, error: NSError!) inif accessGranted == true {// Ensure that UI refreshes happen back on the main thread!dispatch_async(dispatch_get_main_queue(), {self.loadCalendars()self.refreshTableView()})} else {// Ensure that UI refreshes happen back on the main thread!dispatch_async(dispatch_get_main_queue(), {self.needPermissionView.fadeIn()})}})}// …} |
我们的EKEventStore实例提供了一个名为requestAccessToEntityType的函数.再次将EKEntityTypeEvent作为我们请求访问日历的参数传递.剩余的有趣的部分在我们提供的封装完的闭包里能够找到.
在实现里有三个主要的事情需要注意:
传递到闭包里的两个参数一个是用来说明访问权限是否被授予的Bool类型的,另一个是NSError.
我们需要调用dispatch_async(),并表明我们要调回主队列中执行刷新UI的操作.
self.needPermissionView.fadeIn()作为我操作中的一个UIView的拓展,[Swift中渐入/淡出动画的拓展类(Fade In / Out Animations as Class Extensions in Swift)](https://github.com/andrewcbancroft/EventTracker/tree/ask-for-permission).
授予访问权限!加载日历和刷新表视图
当被允许访问的时候,我们可以调用eventStore实例中的calendarsForEntityType函数,并传递EKEntityTypeEvent去抓取用户日历的数组在我们的表视图中显示.下面就来看看:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
loadCalendars() class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { // ... var calendars: [EKCalendar]? // ... func loadCalendars() { self.calendars = eventStore.calendarsForEntityType(EKEntityTypeEvent) as? [EKCalendar] } func refreshTableView() { calendarsTableView.hidden = false calendarsTableView.reloadData() } // ...} |
拒绝访问–显示需要许可视图
当访问被拒绝的时候,我们需要弹出在故事板场景中创建的“Needs Permission View”.
在这个视图中,上面的函数重新被调用,这样有一个能够让用户直接跳转到我们应用程序的设置页面中,以便他们能够从那里授权日历访问.这个按钮连线到了一个IBAction.下面有实现IBAction的例子:
|
1
2
3
4
5
6
7
8
9
|
goToSettingsButtonTapped() class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { // ... @IBAction func goToSettingsButtonTapped(sender: UIButton) { let openSettingsUrl = NSURL(string: UIApplicationOpenSettingsURLString) UIApplication.sharedApplication().openURL(openSettingsUrl!) } // ...} |
结束语
这几乎完成了使用 Event Kit的开始工作!对于checkCalendarAuthorizationStatus()函数的其余案例简单的重用,我只是简单的剖析了请求允许的过程.
我鼓励你们跳到Github,并且作为你应用程序中利用Event Kit的开始,自己深入研究这些代码.
Swift EventKit的初学者指南–请求权限的更多相关文章
- 【系列】Java多线程初学者指南(1):线程简介
原文地址:http://www.blogjava.net/nokiaguy/archive/2009/nokiaguy/archive/2009/03/archive/2009/03/19/26075 ...
- 【翻译】nginx初学者指南
nginx初学者指南 本文翻译自nginx官方网站:http://nginx.org/en/docs/beginners_guide.html#control 该指南会对nginx做一个简要的介绍,同 ...
- Java多线程初学者指南系列教程
转自:http://developer.51cto.com/art/200911/162925.htm 51cto 本系列来自NokiaGuy的“真的有外星人吗”博客,系列名称为<Java多线程 ...
- NHibernate初学者指南系列文章导航
NHibernate初学者指南系列文章导航 前面的话 经过三个多周的时间,终于将这个系列完成了,谢谢大家的关注和支持,有很多不足之处还望大家包涵. 本系列参考的书籍为NHibernate 3 Be ...
- unity+android权限--打开应用不弹权限,动态请求权限
因为笔者之前的游戏需要分享图片,会请求外部储存,第一次打开游戏就会出现弹窗: 很多人对这个很敏感,怕你访问到他们的照片隐私,看到这个权限就拒绝,甚至卸载,实际上我们只是想截屏游戏内容分享给其他玩家,但 ...
- FreeBSD上编写x86 Shellcode初学者指南
FreeBSD上编写x86 Shellcode初学者指南 来源 https://www.4hou.com/binary/14375.html 介绍 本教程的目的是帮助你熟悉如何在FreeBSD操作系统 ...
- 《SQL初学者指南》——第1章 关系型数据库和SQL
第1章 关系型数据库和SQL SQL初学者指南在本章中,我们将介绍一些背景知识,以便于你能够很快地上手,能在后续的章节中编写SQL语句.本章有两个主题.首先是对本书所涉及到的数据库做一个概述,并且介绍 ...
- Python编程初学者指南|百度网盘免费下载|Python新手入门资料
Python编程初学者指南|百度网盘免费下载 提取码:9ozx 目录 · · · · · · 第1章 启程:Game Over程序1.1 剖析Game Over程序1.2 Python简介1.2.1 ...
- 《Python编程初学者指南》高清PDF版|百度网盘免费下载|Python基础
<Python编程初学者指南>|百度网盘免费下载| 提取码:03b1 内容简介 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.Python可以用于很多的领域,从科学计 ...
随机推荐
- Python的filter与map内置函数
简单的记录下这两个函数的功能: list(filter(lambda x : x % 2, range(10))) 上例是返回了0-10之间的所有基数组成的列表.filter()有2个参数,第一个参数 ...
- testNG中方法的调用顺序
今天在执行selnium的test case时,总是遇到空指针错误.但是以前也有run成功过,然后换了各种方法定位元素,都失败了,所以怀疑应该不是元素定位不到的问题,所以可能是method之间有依赖, ...
- APP开发过程的优惠券设计及流程
在整个APP开发产品发展的整个周期中,运营活动必不可少,而发放优惠券已成为运营活动的一种基本形式,而关于优惠券设计的整体流程尤为重要.接下来,常州开发APP公司专家分享一下自己的经验,希望对大家有帮助 ...
- 三.Windows I/O模型之事件选择(WSAEventSelect )模型
1.事件选择模型:和异步选择模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知.对于异步选择模型采用的网络事件来说,它们均可原封不动地移植到事件选择模型.事件选择模型和 ...
- img-responsive class图片响应式
在BootStrap中,给<img>添加 .img-responsive样式就可以实现图片响应式. 1 <img src="..." class="im ...
- MongoDB经典入门(2)--shell命令
MongoDB是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境. 使用 "./mongo --help" 可查看相关连接 ...
- POJ 2486 Apple Tree (树形dp 经典题)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const ...
- java中String和int的互相转化
1. String 转 int 方式1:Integer.parseInt(); 方式2: Integer.valueOf(myStr).intValue(); 2. int 转String 方式1: ...
- 【JavaScript框架封装】公共框架的封装
/* * @Author: 我爱科技论坛 * @Time: 20180706 * @Desc: 实现一个类似于JQuery功能的框架 // 公共框架 // 种子模块:命名空间.对象扩展.数组化.类型的 ...
- AOJ 2224 Save your cats( 最小生成树 )
链接:传送门 题意:有个女巫把猫全部抓走放在一个由 n 个木桩(xi,yi),m 个篱笆(起点终点木桩的编号)围成的法术领域内,我们必须用圣水才能将篱笆打开,然而圣水非常贵,所以我们尽量想降低花费来解 ...