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.

我已经创建了一个设置表视图的简短截屏,如果你想要一个完整的练习,可以参看下面链接的内容:

这里有这些约束的详细视图,以及故事板看起来像装表视图的视觉效果.

最后一点,在故事板中我已经将这个表视图的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!) in

if 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作为我们请求访问日历的参数传递.剩余的有趣的部分在我们提供的封装完的闭包里能够找到.

在实现里有三个主要的事情需要注意:

  1. 传递到闭包里的两个参数一个是用来说明访问权限是否被授予的Bool类型的,另一个是NSError.
  2. 我们需要调用dispatch_async(),并表明我们要调回主队列中执行刷新UI的操作.
  3. 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的开始,自己深入研究这些代码.

时间: 2024-11-09 00:33:04

Swift EventKit的初学者指南–请求权限的相关文章

Swift 的 NSDate 初学者指南

Swift 的 NSDate 初学者指南 2015.12.14 22:43 如果问我在做过的所有项目中做的最多的事情,那处理日期绝对是榜上有名(译注:本文中的「日期」是指代 NSDate 对象,同时包含「日(date)」 和「时(time)」这两个元素).毋庸置疑,无论工作量是多是少,开发者迟早需要「玩」一下 NSDate 类,去按某种方式处理一下日期.从简单的将一个日期转换成一个字符串到对日期做计算,总会有一个不变的事实:开发者必须在 iOS 编程中学会这个知识点.这并不难掌握,而且可以为以后

HTML5 & CSS3初学者指南(3) – HTML5新特性

介绍 本文介绍了 HTML5 的一些新特性.主要包含以下几个方面: Web 存储 地理位置 拖放 服务器发送事件 Web存储 HTML5 Web 存储的设计与构想是一个更好的机制来存储客户端的网络数据.它是通过一个网络浏览器作为客户端数据库实现的,它允许网页以键值对的形式来存储数据. 它具有以下特征: 每个原始网站/域最多可存储 5MB 的数据. 你可以通过属性和方法来使用 JavaScript 操作 web 存储器中的数据实现访问. 就像 cookies,你可以选择将保持数据(维持),即使你已

深网与暗网初学者指南

揭秘深网和暗网:你所不知道的互联网 事物总有正反面,网络也一样,其中的深网和暗网(互联网中无法被搜索引擎抓取到的那部分网络)已经存在多年了,不过在IoE(Internet of Everything万物互联)时代,它可能会扮演更为重要的角色. 我们时常会听到有人提起一个不为人知的网络,也就是所谓的暗网. 如果不是发生了一些大事(比如最近的丝绸之路2.0事件),可能大多数人一辈子都不会听到暗网这个名词.不过现在这个情况正在慢慢改变,一旦IoE的进化得以实现,再加上各类渗透,暗网的融合趋势便不可阻挡

HTML5&CSS3初学者指南(1) – 编写第一行代码

介绍 网络时代已经到来.现在对人们来说,每天上网冲浪已经成为一种最为常见的行为. 在网页浏览器中输入一段文本地址,就像http://www.codeproject.com,等待一下,网页就加载到浏览器窗口中.一个典型的网页是由文本.图像和链接组成的.除去内容上的差异,不同网站的网页也具有不同的外观和感受,以实现在网络上建立自己的身份品牌的目的. 如果你也曾想要了解你屏幕上的这些网页是如何被创建出并以各式各样的方式渲染的,那么这里正是你可以了解到这些知识的地方.让我们一起走进在浏览器中创建了这么多

算法初学者指南

摘自网络,对于这个训练计划,我只能膜拜,~ 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15 分钟内打完,甚至关掉显示器都可以把程序打 出来. 1.最短路(Floyd.Dijstra,BellmanFord) 2. 最小生成树(先写个prim,kruscal要用并查集,不好写) 3.大数(高精度)加减乘除 4.二分查找. (代码可在五行以内) 5.叉乘.判线段相交.然后写个凸包. 6.BFS.DFS,同时熟练hash表(

HTML5 & CSS3 初学者指南(4) – Canvas使用

介绍 传统的HTML主要用于文本的创建,可以通过<img>标签插入图像,动画的实现则需要第三方插件.在这方面,传统的HTML极其缺乏满足现代网页多媒体需求的能力.HTML5的到来,带来了新的成员<canvas>标签. 什么是 Canvas? HTML5 的 Canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,你可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. 创建 Canvas 元素 向 HTML5 页面添

HTML5 & CSS3初学者指南(2) – 样式化第一个网页

介绍 我们已经使用基本的 HTML 编写了一个网页.但是,写出来的 HTML 代码的网页看起来很平淡,没有吸引力. 如何改善这种很平淡的页面呢? 让我们开始使用网页的基本样式来改善页面效果,我们将会使用到 CSS 的功能. 正式开始 CSS 是层叠样式表的缩写,它是为网页添加样式的通用语言,在所有浏览器中都支持.最新的标准是 CSS3,这与早期版本完全向后兼容.CSS3 的规范是由 W3C 开发的,目前仍处于开发阶段,其最新的版本是 CSS Snapshot 2010. 打开你的文本编辑器,键入

RMAN 初学者指南

说明转自一个大神的笔记. RMAN 初学者指南  这篇文章是去年写的了,最初发表在chinaunix.net的oracle论坛里,收录在旧版文集中,可能很多没有看到,总有人写信要,今天乘改版之际就把它单独拿出来了. RMAN(Recovery Manager)是DBA的一个重要工具,用于备份.还原和恢复oracle数据库,前一段时间有网友找我要,可惜没时间,趁这两天出差在外没什么事,就写了一下,供初学的朋友参考.本文将介绍RMAN 的基本操作,更多的信息请参考<Oracle8i Backup &am

app在android 6.0或以上平台版本运行过程中请求权限

原文作者:Google 原文地址:http://developer.android.com/intl/zh-cn/training/permissions/requesting.html 原文版权:Creative Commons 2.5 Attribution License 译文作者:Jianan - [email protected] 版本信息:本文基于2016-04-27版本翻译 译文版权:CC BY-NC-ND 4.0,允许复制转载,但必须保留译文作者署名及译文链接,不得演绎和用于商业