最近公司項目中有個地方需要將軟件的備忘錄同步到系統(tǒng)中,由系統(tǒng)來提醒,網(wǎng)上也有類似的例子,做了配置后日歷沒什么問題,但是提醒事項就不行,切斷點看原因
Error getting default calendar for new reminders
error=Error Domain=EKErrorDomain Code=1 "No calendar has been set." UserInfo
大體就是獲取提醒時出錯,然而看了好多中文網(wǎng)的例子都沒出現(xiàn)過這種錯誤,都是Error getting default calendar for newEvent 這種錯誤,然后我用了他們寫的demo也是運行不出來,我當時就在想難道都沒遇到過這種調(diào)用提醒事項出錯的么,其實大家心里都清楚,很多都是復(fù)制別人的博客,真正去敲代碼的很少,失望下去看國外的技術(shù)博客,外語水平一般,勉強能看懂,發(fā)現(xiàn)不少和我遇到類似的情況,不過他們解決的方式不一樣,總結(jié)如下:
一,不論要調(diào)取系統(tǒng)的相冊或者語音,或者日歷和提醒事項,那么都要在plist文件中進行設(shè)置
二,然后就是需要請求系統(tǒng)的權(quán)限,每一個都要請求
我就是在這步錯的,網(wǎng)上的一些人誤導(dǎo)了我,這里粘貼處別人的代碼,其中分割線中間的部分可以看到是請求的系統(tǒng)日歷權(quán)限,如果通過繼續(xù)保存,
+ (void)saveEventStartDate:(NSDate*)startData endDate:(NSDate*)endDate alarm:(float)alarm eventTitle:(NSString*)eventTitle location:(NSString*)location isReminder:(BOOL)isReminder{
//事件市場
EKEventStore *eventStore = [[EKEventStore alloc] init];
//6.0及以上通過下?面?方式寫?入事件
if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//等待用戶是否同意授權(quán)日歷
//EKEntityMaskEvent提醒事項參數(shù)(該參數(shù)只能真機使用)? EKEntityTypeEvent日歷時間提醒參數(shù)
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
}else if (!granted)
{
//被?用戶拒絕,不允許訪問?日歷
}else{
//事件保存到?日歷
//創(chuàng)建事件
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = eventTitle;
event.location = location;
//設(shè)定事件開始時間
//[NSDate dateWithTimeIntervalSinceNow:10];
event.startDate=startData;
//設(shè)定事件結(jié)束時間
//[NSDate dateWithTimeIntervalSinceNow:20];
event.endDate=endDate;
//添加提醒 可以添加多個轧邪,設(shè)定事件多久以前開始提醒
// event.allDay = YES;
//在事件前多少秒開始事件提醒-5.0f
[event addAlarm:[EKAlarm alarmWithRelativeOffset:alarm]];
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
NSLog(@"保存成功");
//是否寫入提醒事項褐澎,提醒事項為iOS原生自帶的,但是模擬器沒有的,這個地方說IOS原生自帶,看了10個博文幾乎都一模一樣,給人誤導(dǎo)不用請求提醒事項不用申請,這個地方也需要申請,我再下面自己的代碼里寫了申請?zhí)嵝咽马?如果直接用他的,在這個地方打斷點reminder.calendar=[eventStore defaultCalendarForNewReminders];會發(fā)現(xiàn)為空,因為沒去獲取系統(tǒng)的權(quán)限,那么調(diào)用defaultCalendarForNewReminders根本不行,雖然不會報錯
if (isReminder) {
EKCalendar * iDefaultCalendar = [eventStore defaultCalendarForNewReminders];
EKReminder *reminder=[EKReminder reminderWithEventStore:eventStore];
reminder.calendar=[eventStore defaultCalendarForNewReminders];
reminder.title=eventTitle;
reminder.calendar = iDefaultCalendar;
EKAlarm *alarm=[EKAlarm alarmWithAbsoluteDate:[NSDate dateWithTimeIntervalSinceNow:-10]];
[reminder addAlarm:alarm];
NSError *error=nil;
[eventStore saveReminder:reminder commit:YES error:&error];
if (error) {
NSLog(@"error=%@",error);
}
}
}
});
}];
}else{
//4.0和5.0通過下述?方式添加 無需判斷用戶是否同意訪問日歷
//事件保存到?日歷
//創(chuàng)建事件
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = eventTitle;
event.location = location;
//設(shè)定事件開始時間
//[NSDate dateWithTimeIntervalSinceNow:10];
event.startDate=startData;
//設(shè)定事件結(jié)束時間
//[NSDate dateWithTimeIntervalSinceNow:20];
event.endDate=endDate;
//添加提醒 可以添加多個舔涎,設(shè)定事件多久以前開始提醒
// event.allDay = YES;
//在事件前多少秒開始事件提醒-5.0f
[event addAlarm:[EKAlarm alarmWithRelativeOffset:alarm]];
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
[eventStore saveEvent:event span:EKSpanThisEvent error:&err];
NSLog(@"保存成功");
//是否寫入提醒事項誊役,提醒事項為iOS原生自帶的获列,但是模擬器沒有的
if (isReminder) {
EKCalendar * iDefaultCalendar = [eventStore defaultCalendarForNewReminders];
EKReminder *reminder=[EKReminder reminderWithEventStore:eventStore];
reminder.calendar=[eventStore defaultCalendarForNewReminders];
reminder.title=eventTitle;
reminder.calendar = iDefaultCalendar;
EKAlarm *alarm=[EKAlarm alarmWithAbsoluteDate:[NSDate dateWithTimeIntervalSinceNow:-10]];
[reminder addAlarm:alarm];
NSError *error=nil;
[eventStore saveReminder:reminder commit:YES error:&error];
if (error) {
NSLog(@"error=%@",error);
}
}
}
}
以上都是我對別人的錯誤代碼進行的解析,下面我自己增加了一個方法用來增加的提醒事項,因為我只需要添加提醒事項部分,所以就只寫了調(diào)用提醒事項,日歷等同,上面的代碼也實現(xiàn)了日歷的調(diào)用,只不過沒實現(xiàn)提醒事項的.其實我的這部分就是抽出來了增加提醒事項的部分,并增加了申請系統(tǒng)提醒事項權(quán)限的代碼,沒多少.
data就是提醒時間,可以任意比如:
NSDate*startData=[NSDate dateWithTimeIntervalSinceNow:10];
title是提醒內(nèi)容
-(void)addReminderNotify:(NSDate *)date title:(NSString *)title
{
//事件市場
EKEventStore *eventStore = [[EKEventStore alloc] init];
//6.0及以上通過下?面?方式寫?入事件
if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//等待用戶是否同意授權(quán)日歷
//EKEntityMaskEvent提醒事項參數(shù)(該參數(shù)只能真機使用)? EKEntityTypeEvent日歷時間提醒參數(shù)
[eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
}else if (!granted)
{
//被?用戶拒絕,不允許訪問?日歷
}else{
//事件保存到?日歷
//創(chuàng)建事件
EKCalendar * iDefaultCalendar = [eventStore defaultCalendarForNewReminders];
EKReminder *reminder=[EKReminder reminderWithEventStore:eventStore];
reminder.title= title;
reminder.calendar = iDefaultCalendar;
EKAlarm *alarm=[EKAlarm alarmWithAbsoluteDate:date];
[reminder addAlarm:alarm];
EKCalendar *targetCalendar = nil;
if (eventStore.defaultCalendarForNewReminders == nil) {
EKEventStore? *eventStores = [[EKEventStore alloc] init];
targetCalendar = [eventStores defaultCalendarForNewReminders];
[reminder setCalendar:targetCalendar];
}else
{
[reminder setCalendar:[eventStore defaultCalendarForNewReminders]];
}
NSError *error=nil;
[eventStore saveReminder:reminder commit:YES error:&error];
if (error) {
NSLog(@"error=%@",error);
}
}
});
}];
}
}
我也是喜歡看別人的例子,懶得自己琢磨,希望我的經(jīng)歷可以給別人一些小提示.??