Swift EventKit的初學(xué)者指南C請求權限

EventKit為獲取和操作用戶(hù)日歷事件和提醒提供了一系列的類(lèi).在下面的教程中,我的目標是帶領(lǐng)你走出利用EventKit建立一個(gè)應用程序的第.我的目標是帶領(lǐng)你邁出利用EventKit建立一個(gè)應用程序的第一步.我將演示如何向用戶(hù)的日歷請求許可,我還將展示幾個(gè)處理用戶(hù)響應的例子(當他們授予訪(fǎng)問(wèn)權限,或者拒絕).
Example scenario
場(chǎng)景
讓我們先提出一個(gè)基本方案,作為本教程的例子。
假設我們正在構建一個(gè)應用程序,現在,有一個(gè)單一的視圖控制器。在得到用戶(hù)授權允許的情況下,我們希望這個(gè)視圖控制器顯示日歷列表。如果用戶(hù)拒絕訪(fǎng)問(wèn),我們將向用戶(hù)展示一個(gè)消息,用來(lái)說(shuō)明我們的應用程序在沒(méi)有訪(fǎng)問(wèn)權限時(shí)不能運行,我們也將允許他們通過(guò)單擊一個(gè)按鈕能夠在他們的設備的設置中設置授權訪(fǎng)問(wèn).
我已經(jīng)創(chuàng )建一個(gè)那樣的應用程序作為例子–跳到GitHub中查看并研究這個(gè)例子的代碼.
資源
Xcode工程示例
Storyboard setup
故事面板設置
你使用EventKit的第一步就是需要為自己創(chuàng )建一個(gè)用戶(hù)界面來(lái)處理當你第一個(gè)程序啟動(dòng)時(shí)用戶(hù)對”該程序可以訪(fǎng)問(wèn)你的日歷嗎?”對出不同的響應,不久,我們將得到如何請求這個(gè)許可的詳情.但首先,讓我們來(lái)剖析我們如何用對于一個(gè)許可操作導致的給定響應能夠做正確的操作的一些視圖來(lái)安排我們的故事板.
用戶(hù)可以授予訪(fǎng)問(wèn)權限,也可以拒絕授予訪(fǎng)問(wèn)權限來(lái)通知他們的日歷或者提醒.我們需要為這兩種情況做好準備.
當被授予訪(fǎng)問(wèn)權限時(shí),tableview顯示日歷列表
我今天持樂(lè )觀(guān)態(tài)度,所以讓我們開(kāi)始處理從一開(kāi)始用戶(hù)就授予我們訪(fǎng)問(wèn)他們日歷的權限的情況.
當用戶(hù)授予我們訪(fǎng)問(wèn)權限,我們想列出一個(gè)表視圖的日歷.在接下來(lái)的教程中,我們將擔心數據源的設置.現在,我們將從實(shí)用工具欄中拽一個(gè)表格視圖過(guò)來(lái).
為了得到填滿(mǎn)整個(gè)屏幕的表視圖,我做了幾件事情.通常,當你從實(shí)用工具欄中拽一個(gè)表視圖過(guò)來(lái)的時(shí)候,它會(huì )在故事板中填滿(mǎn)整個(gè)場(chǎng)景.在布局中我向下拖頂部邊緣知道它”捕捉”到我所期望的狀態(tài)欄底部被定位的那行.然后,我設置了以下限制:
Center X
Center Y
Equal width to Superview
Top space to Top Layout Guide for height.
我已經(jīng)創(chuàng )建了一個(gè)設置表視圖的簡(jiǎn)短截屏,如果你想要一個(gè)完整的練習,可以參看下面鏈接的內容:
Resources
資源
Screencast: Setting Up a Table View
Full transcript
這里有這些約束的詳細視圖,以及故事板看起來(lái)像裝表視圖的視覺(jué)效果.


最后一點(diǎn),在故事板中我已經(jīng)將這個(gè)表視圖的hidden屬性設置為true.根據用戶(hù)允許或者拒絕對日歷的訪(fǎng)問(wèn)后,我將切換表的可見(jiàn)性,但我認為值得指出的是在我例子中表視圖的初始狀態(tài)是被隱藏.
訪(fǎng)問(wèn)被拒絕時(shí)的”需要許可”視圖
但有時(shí),用戶(hù)拒絕授權訪(fǎng)問(wèn)日歷,在意識到這樣做將導致基本上停止你應用程序所有的功能之前,如果你的整個(gè)應用程序或者只是該應用程序的一部分需要訪(fǎng)問(wèn)功能,你需要一種方法來(lái)告知用戶(hù),并為他們提供一種方法跳到用戶(hù)設置,如果可能的話(huà)讓用戶(hù)手動(dòng)授予訪(fǎng)問(wèn)權限.
我在示例項目中的方法是在故事板場(chǎng)景中組織一個(gè)新的視圖,該視圖包含一個(gè)展示操作說(shuō)明的標簽和一個(gè)點(diǎn)擊后使用戶(hù)進(jìn)入我們應用程序的設置界面的按鈕.
再次,一些約束涉及到在運行時(shí)使一些事物正確的顯示.在這里我不會(huì )講述這個(gè)細節,因為它很可能因為每一個(gè)執行操作而有一點(diǎn)不同.
我將指出的意見(jiàn)事情是,這個(gè)視圖的透明度已經(jīng)被設置為0,以便如果用戶(hù)拒絕授權,我能夠展示一個(gè)逐漸消失的效果.下面就來(lái)看看在設置了隱藏“NeedPermissionsView”的場(chǎng)景:
blob.png
Event Store的角色
EventKit的核心是EKEventStore.EKEventStore是事物的中心.創(chuàng )建EKEventStore的一個(gè)實(shí)例,為開(kāi)發(fā)人員提供了對用戶(hù)的日歷和提醒列表中執行各種讀/寫(xiě)操作的API.
一個(gè)與日歷交互的視圖控制器應該有一個(gè)引用EKEventStore的實(shí)例.這很容易被創(chuàng )建–這里是一個(gè)例子:
ViewController.swift
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { let eventStore = EKEventStore() // ... }
檢查日歷的授權
一旦我們有了引用EKEventStore的實(shí)例,我們可以做像檢查用戶(hù)是否授權訪(fǎng)問(wèn)他們的日歷這樣的事情.根據這里,我們可以做是否需要請求許可的決定,隨后確定要顯示的視圖(表視圖或者需要許可視圖).
我們在哪里檢查日歷授權很重要.我的建議是每次在視圖出現時(shí)檢查(即在viewWillAppear()中),因為用戶(hù)首次授予訪(fǎng)問(wèn)權限,切換設置,拒絕訪(fǎng)問(wèn)的情況是完全有可能的.我們的應用程序需要做出適當的響應.
In the example project provided with this article, I’ve created a function named checkCalendarAuthorizationStatus(). Here a peek at what it does:
在這個(gè)文章提供的示例工程中,我已經(jīng)創(chuàng )建了一個(gè)名為checkCalendarAuthorizationStatus()的函數.
接下來(lái)看看它的實(shí)現:
ViewController.swift
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() } } // ... }
這里關(guān)鍵的功能是EKEventStore的 authorizationStatusForEntityType實(shí)現的.傳入的EKEntityTypeEvent用于跟用戶(hù)日歷進(jìn)行交互.如果我們想要檢查他們的提醒的權限,我們將在這里使用EKEntityTypeReminder.
EKAuthorizationStatus的可能值根據switch里的相應的case來(lái)執行封裝好的方便閱讀的獨立功能的邏輯代碼.
讓我們一步步來(lái)看一看這些功能.
請求訪(fǎng)問(wèn)日歷
正如標題所說(shuō)的,所有的事情從這里開(kāi)始.每當我們的應用程序加載和調用authorizationStatusForEntityType的時(shí)候,將返回NotDetermined的狀態(tài).就是在這一點(diǎn)上我們想請求訪(fǎng)問(wèn)日歷.
為了這樣做,按照下面的方法定義requestAccessToCalendar函數:
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實(shí)例提供了一個(gè)名為requestAccessToEntityType的函數.再次將EKEntityTypeEvent作為我們請求訪(fǎng)問(wèn)日歷的參數傳遞.剩余的有趣的部分在我們提供的封裝完的閉包里能夠找到.
在實(shí)現里有三個(gè)主要的事情需要注意:
傳遞到閉包里的兩個(gè)參數一個(gè)是用來(lái)說(shuō)明訪(fǎng)問(wèn)權限是否被授予的Bool類(lèi)型的,另一個(gè)是NSError.
我們需要調用dispatch_async(),并表明我們要調回主隊列中執行刷新UI的操作.
self.needPermissionView.fadeIn()作為我操作中的一個(gè)UIView的拓展,[Swift中漸入/淡出動(dòng)畫(huà)的拓展類(lèi)(Fade In / Out Animations as Class Extensions in Swift)](https://github.com/andrewcbancroft/EventTracker/tree/ask-for-permission).
授予訪(fǎng)問(wèn)權限!加載日歷和刷新表視圖
當被允許訪(fǎng)問(wèn)的時(shí)候,我們可以調用eventStore實(shí)例中的calendarsForEntityType函數,并傳遞EKEntityTypeEvent去抓取用戶(hù)日歷的數組在我們的表視圖中顯示.下面就來(lái)看看:
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() } // ... }
拒絕訪(fǎng)問(wèn)–顯示需要許可視圖
當訪(fǎng)問(wèn)被拒絕的時(shí)候,我們需要彈出在故事板場(chǎng)景中創(chuàng )建的“Needs Permission View”.
在這個(gè)視圖中,上面的函數重新被調用,這樣有一個(gè)能夠讓用戶(hù)直接跳轉到我們應用程序的設置頁(yè)面中,以便他們能夠從那里授權日歷訪(fǎng)問(wèn).這個(gè)按鈕連線(xiàn)到了一個(gè)IBAction.下面有實(shí)現IBAction的例子:
goToSettingsButtonTapped() class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { // ... @IBAction func goToSettingsButtonTapped(sender: UIButton) { let openSettingsUrl = NSURL(string: UIApplicationOpenSettingsURLString) UIApplication.sharedApplication().openURL(openSettingsUrl!) } // ... }
結束語(yǔ)
這幾乎完成了使用 Event Kit的開(kāi)始工作!對于checkCalendarAuthorizationStatus()函數的其余案例簡(jiǎn)單的重用,我只是簡(jiǎn)單的剖析了請求允許的過(guò)程.
我鼓勵你們跳到Github,并且作為你應用程序中利用Event Kit的開(kāi)始,自己深入研究這些代碼.
評論