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其骄;自己計算一下嘍?髁!拯爽!