iOS中調(diào)用系統(tǒng)日歷 - <EventKit/EventKit.h> 和實用類(在下面)

1.首先簡單了解 EventKit ---- 摘自http://docs.xamarin.com/guides/ios/platform_features/introduction_to_eventkit/

概述

iOS有兩個內(nèi)建的日歷應(yīng)用:Calendar唁盏,Reminders翔忽。很顯然能看出Calendar是管理日歷數(shù)據(jù)的,而Reminders卻不是特別顯而易見扫责。Reminders擁有在指定時間安排州邢、完成等等的事件的日期鉴腻。比如这嚣,iOS存儲著所有的日歷數(shù)據(jù)烙博,無論它屬于日歷事件(calendar events)或者提醒(reminders)瑟蜈,他們都屬于日歷數(shù)據(jù)庫(Calendar Database)烟逊。

EventKit框架提供了一種訪問存儲在日歷數(shù)據(jù)庫(Calendar Database)的日歷、日歷事件铺根、提醒數(shù)據(jù)的方式宪躯。iOS4開始就支持訪問日歷和日歷事件、而iOS6起增加支持訪問提醒位迂。

必要條件

EventKit是在iOS4.0提出的访雪,但訪問提醒(Reminders)是在iOS6中提出。這樣的話掂林,通常做EventKit 開發(fā)臣缀,使用日歷要基于iOS4.0,提醒需要基于iOS6泻帮。

另外精置,Reminders應(yīng)用程序不適用于模擬器,這意味著提醒數(shù)據(jù)是不可以用的锣杂,除非你先添加了他們脂倦。還有,訪問請求(assess requests)只在真實設(shè)備上展示給用戶元莫。這樣的話赖阻,EventKit開發(fā)要基于真實設(shè)備來測試。

Event Kit 基礎(chǔ)

當(dāng)我們使用EventKit的時候踱蠢,重要的是掌握常用類和他們的用法火欧。所有的類(Class)都可以在MonoTouch.EventKit 和 MonoTouch.EventKitUI(for the EKEventEditController)中找到.

EventStore

EventStore是EventKit中最重要的類,因為在EventKit中執(zhí)行的任何操作都需要它朽基。EventStore可以認(rèn)為是 持久存儲器 或者 數(shù)據(jù)庫布隔,EventKit數(shù)據(jù)的引擎。從EventStore中稼虎,你可以訪問到Calendar應(yīng)用程序中得日歷還有日歷事件衅檀,當(dāng)然還有Reminders應(yīng)用中得提醒。

因為EventStore很像一個數(shù)據(jù)庫引擎霎俩,所以他應(yīng)該長久持有哀军,這意味著在應(yīng)用的生命周期內(nèi)它應(yīng)該盡可能的少創(chuàng)建、銷毀打却。實際杉适,建議這樣:一旦你在應(yīng)用中創(chuàng)建了一個EventStore酱塔,你應(yīng)該在應(yīng)用的生命周期內(nèi)保持它(EventStore)的引用翎苫,除非你確定你再不使用它了够颠。另外肪跋,所有的調(diào)用都針對魚一個EventStore實例延届。所以呢偏螺,推薦單例模式乡摹。

Creating an Event Store

下面的代碼再层,說明了一個簡單而有效方式創(chuàng)建一個EventStore的單例,使它在應(yīng)用中靜態(tài)存在秽五。

public class App

{
    public static App Current {

            get { return current; }

    }

    private static App current;

    public EKEventStore EventStore {
            get { return eventStore; }
    }
    protected EKEventStore eventStore;

    static App ()
    {
            current = new App();
    }
    protected App () 
    {
            eventStore = new EKEventStore ( );
    }
}

上面的代碼在應(yīng)用加載的時候 使用了單例模式實現(xiàn)了EventStore對象孽查。這個對象能夠全局訪問,例如:

App.Current.EventStore;
請求 日歷 和 提醒 數(shù)據(jù)

在允許通過EventStore訪問任何數(shù)據(jù)之前坦喘,應(yīng)用程序必須首先獲取權(quán)限盲再,無論日歷事件(calendar event)還是 提醒數(shù)據(jù)(reminders data),取決于你瓣铣。為此答朋,EventStore暴露了一個方法RequestAccess,當(dāng)調(diào)用它的時候坯沪,系統(tǒng)會彈出一個提示框給用戶绿映,告訴用戶應(yīng)用程序請求訪問日歷數(shù)據(jù)或者提醒數(shù)據(jù)。因為有提示框腐晾,所以這個調(diào)用是異步的叉弦,并且完成后會有一個帶兩個參數(shù)(一個bool類型的granted和 NSError)的回調(diào)被調(diào)用,指出是否獲取到權(quán)限訪問藻糖。

下面代碼就是請求權(quán)限訪問日歷事件:


 App.Current.EventStore.RequestAccess (EKEntityType.Event, 
         (bool granted, NSError e) => {
                 if (granted)
                         //do something here
                 else
                         new UIAlertView ( "Access Denied", "User Denied Access to Calendar Data", null,"ok", null).Show ();
                 } );

一旦請求被允許淹冰,這個應(yīng)用只要安裝在設(shè)備上,那么就不會在被彈出再提示巨柒。但是樱拴,權(quán)限只是允許訪問給出的資源類型,是日歷事件或提醒洋满。如果一個應(yīng)用需要這兩種都能訪問晶乔,那就都要請求。

因為權(quán)限是被緩存的了牺勾,那么每次請求相對輕松正罢,所以在每個操作之前都請求權(quán)限是個不錯的主意。

另外驻民,因為回調(diào)方法是在非UI線程中調(diào)用的翻具,所以所有更新UI得操作都要在Main Thread調(diào)用,否則就會引發(fā)異常回还。

EKEntityType

這是個描述EventKit或者數(shù)據(jù)的類型 的枚舉類型裆泳,它有兩個值:Event、Reminder柠硕。它在很多方法中被使用工禾,包括EventStore的RequestAccess方法,告訴EventKit要獲取什么類型的數(shù)據(jù)權(quán)限。

EKCalendar

EKCalendar相當(dāng)于一個日歷帜篇,包含了一組日歷事件糙捺,日歷能夠存儲在很多地方,例如 本地笙隙、iCloud、第三方商:Exchange Sever 或者Google坎缭。大多時候竟痰,EKCalendar被用來告知EventKit,事件從何查找掏呼,存儲到哪里坏快。

EKEventEditController

EKEventEditController能夠在MonoTouch.EventKitUI中找到,它是個內(nèi)建的控制器憎夷,用于創(chuàng)建修改日歷事件莽鸿。這很像內(nèi)建的相機(jī)控制器,EKEventEditController幫你做了繁重的UI和保存數(shù)據(jù)的工作拾给。

EKEvent

EKEvent相當(dāng)于一個日歷祥得,不管是EKEvent還是EKReminder都繼承于EKCalendarItem,他們都有Title蒋得、Notes等字段级及。

EKReminder
EKReminder相當(dāng)于一個提醒事項。
EKSpan

EKSpan是個當(dāng)修改事件為可重復(fù)的時候用于描述事件的跨度的枚舉值额衙,它有兩個值:ThisEvent饮焦、FutureEvents。ThisEvent意味著任何改變窍侧,只會發(fā)生在被引用的一系列特定事件县踢,而FutureEvents會影響事件和所有未來的復(fù)發(fā)。

下面來點實際的代碼:

#import <Foundation/Foundation.h>

@interface EventCalendar : NSObject

+ (instancetype)sharedEventCalendar;

/**
*  將App事件添加到系統(tǒng)日歷提醒事項伟件,實現(xiàn)鬧鈴提醒的功能
*
*  @param title      事件標(biāo)題
*  @param location   事件位置
*  @param startDate  開始時間
*  @param endDate    結(jié)束時間
*  @param allDay     是否全天
*  @param alarmArray 鬧鐘集合
*  @param block      回調(diào)方法
*/
- (void)createEventCalendarTitle:(NSString *)title location:(NSString *)location startDate:(NSDate *)startDate endDate:(NSDate *)endDate allDay:(BOOL)allDay alarmArray:(NSArray *)alarmArray;

@end

#import "EventCalendar.h"
#import <EventKit/EventKit.h>
#import <UIKit/UIKit.h>

@implementation EventCalendar

static EventCalendar *calendar;

+ (instancetype)sharedEventCalendar{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        calendar = [[EventCalendar alloc] init];
    });
    
    return calendar;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        calendar = [super allocWithZone:zone];
    });
    return calendar;
}

- (void)createEventCalendarTitle:(NSString *)title location:(NSString *)location startDate:(NSDate *)startDate endDate:(NSDate *)endDate allDay:(BOOL)allDay alarmArray:(NSArray *)alarmArray{
    __weak typeof(self) weakSelf = self;
    
    EKEventStore *eventStore = [[EKEventStore alloc] init];
    
    if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)])
    {
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error){
            
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (error)
                {
                    [strongSelf showAlert:@"添加失敗硼啤,請稍后重試"];
    
                }else if (!granted){
                    [strongSelf showAlert:@"不允許使用日歷,請在設(shè)置中允許此App使用日歷"];
                    
                }else{
                    EKEvent *event  = [EKEvent eventWithEventStore:eventStore];
                    event.title     = title;
                    event.location = location;
                    
                    NSDateFormatter *tempFormatter = [[NSDateFormatter alloc]init];
                    [tempFormatter setDateFormat:@"dd.MM.yyyy HH:mm"];
                    
                    event.startDate = startDate;
                    event.endDate   = endDate;
                    event.allDay = allDay;
                    
                    //添加提醒
                    if (alarmArray && alarmArray.count > 0) {
                        
                        for (NSString *timeString in alarmArray) {
                            [event addAlarm:[EKAlarm alarmWithRelativeOffset:[timeString integerValue]]];
                        }
                    }
                    
                    [event setCalendar:[eventStore defaultCalendarForNewEvents]];
                    NSError *err;
                    [eventStore saveEvent:event span:EKSpanThisEvent error:&err];
                    [strongSelf showAlert:@"已添加到系統(tǒng)日歷中"];
           
                }
            });
        }];
    }
}

- (void)showAlert:(NSString *)message
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
    [alert show];
}

@end


這里需要注意的地方 :如果需要在時間發(fā)生前提醒用戶,需要傳入提醒時間數(shù)組锋爪,這個數(shù)組是按照秒計算的丙曙。比如時間發(fā)生前一天提醒,時間數(shù)組的元素就是:-86400其骄;自己計算一下嘍?髁!拯爽!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末索抓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逼肯,老刑警劉巖耸黑,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異篮幢,居然都是意外死亡大刊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門三椿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缺菌,“玉大人,你說我怎么就攤上這事搜锰“橛簦” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵蛋叼,是天一觀的道長焊傅。 經(jīng)常有香客問我,道長狈涮,這世上最難降的妖魔是什么狐胎? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮薯嗤,結(jié)果婚禮上顽爹,老公的妹妹穿的比我還像新娘。我一直安慰自己骆姐,他們只是感情好镜粤,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玻褪,像睡著了一般肉渴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上带射,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天同规,我揣著相機(jī)與錄音,去河邊找鬼窟社。 笑死券勺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灿里。 我是一名探鬼主播关炼,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼匣吊!你這毒婦竟也來了儒拂?” 一聲冷哼從身側(cè)響起寸潦,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎社痛,沒想到半個月后见转,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蒜哀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年斩箫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凡怎。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡校焦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出统倒,到底是詐尸還是另有隱情,我是刑警寧澤氛雪,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布房匆,位于F島的核電站,受9級特大地震影響报亩,放射性物質(zhì)發(fā)生泄漏浴鸿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一弦追、第九天 我趴在偏房一處隱蔽的房頂上張望岳链。 院中可真熱鬧,春花似錦劲件、人聲如沸掸哑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苗分。三九已至,卻和暖如春牵辣,著一層夾襖步出監(jiān)牢的瞬間摔癣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工纬向, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留择浊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓逾条,卻偏偏與公主長得像琢岩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子膳帕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容