最近公司項(xiàng)目中有個(gè)地方需要將軟件的備忘錄同步到系統(tǒng)中,由系統(tǒng)來(lái)提醒,網(wǎng)上也有類似的例子,做了配置后日歷沒什么問題,但是提醒事項(xiàng)就不行,切斷點(diǎn)看原因
Error getting default calendar for new reminders
error=Error Domain=EKErrorDomain Code=1 "No calendar has been set." UserInfo
大體就是獲取提醒時(shí)出錯(cuò),然而看了好多中文網(wǎng)的例子都沒出現(xiàn)過(guò)這種錯(cuò)誤,都是Error getting default calendar for newEvent 這種錯(cuò)誤,然后我用了他們寫的demo也是運(yùn)行不出來(lái),我當(dāng)時(shí)就在想難道都沒遇到過(guò)這種調(diào)用提醒事項(xiàng)出錯(cuò)的么,其實(shí)大家心里都清楚,很多都是復(fù)制別人的博客,真正去敲代碼的很少,失望下去看國(guó)外的技術(shù)博客,外語(yǔ)水平一般,勉強(qiáng)能看懂,發(fā)現(xiàn)不少和我遇到類似的情況,不過(guò)他們解決的方式不一樣,總結(jié)如下:
一,不論要調(diào)取系統(tǒng)的相冊(cè)或者語(yǔ)音,或者日歷和提醒事項(xiàng),那么都要在plist文件中進(jìn)行設(shè)置

二,然后就是需要請(qǐng)求系統(tǒng)的權(quán)限,每一個(gè)都要請(qǐng)求
我就是在這步錯(cuò)的,網(wǎng)上的一些人誤導(dǎo)了我,這里粘貼處別人的代碼,其中分割線中間的部分可以看到是請(qǐng)求的系統(tǒng)日歷權(quán)限,如果通過(guò)繼續(xù)保存,
+ (void)saveEventStartDate:(NSDate*)startData endDate:(NSDate*)endDate alarm:(float)alarm eventTitle:(NSString*)eventTitle location:(NSString*)location isReminder:(BOOL)isReminder{
//事件市場(chǎng)
EKEventStore *eventStore = [[EKEventStore alloc] init];
//6.0及以上通過(guò)下?面?方式寫?入事件
if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//等待用戶是否同意授權(quán)日歷
//EKEntityMaskEvent提醒事項(xiàng)參數(shù)(該參數(shù)只能真機(jī)使用)? EKEntityTypeEvent日歷時(shí)間提醒參數(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è)定事件開始時(shí)間
//[NSDate dateWithTimeIntervalSinceNow:10];
event.startDate=startData;
//設(shè)定事件結(jié)束時(shí)間
//[NSDate dateWithTimeIntervalSinceNow:20];
event.endDate=endDate;
//添加提醒 可以添加多個(gè),設(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(@"保存成功");
//是否寫入提醒事項(xiàng),提醒事項(xiàng)為iOS原生自帶的,但是模擬器沒有的,這個(gè)地方說(shuō)IOS原生自帶,看了10個(gè)博文幾乎都一模一樣,給人誤導(dǎo)不用請(qǐng)求提醒事項(xiàng)不用申請(qǐng),這個(gè)地方也需要申請(qǐng),我再下面自己的代碼里寫了申請(qǐng)?zhí)嵝咽马?xiàng),如果直接用他的,在這個(gè)地方打斷點(diǎn)reminder.calendar=[eventStore defaultCalendarForNewReminders];會(huì)發(fā)現(xiàn)為空,因?yàn)闆]去獲取系統(tǒng)的權(quán)限,那么調(diào)用defaultCalendarForNewReminders根本不行,雖然不會(huì)報(bào)錯(cuò)
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通過(guò)下述?方式添加 無(wú)需判斷用戶是否同意訪問日歷
//事件保存到?日歷
//創(chuàng)建事件
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = eventTitle;
event.location = location;
//設(shè)定事件開始時(shí)間
//[NSDate dateWithTimeIntervalSinceNow:10];
event.startDate=startData;
//設(shè)定事件結(jié)束時(shí)間
//[NSDate dateWithTimeIntervalSinceNow:20];
event.endDate=endDate;
//添加提醒 可以添加多個(gè),設(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(@"保存成功");
//是否寫入提醒事項(xiàng),提醒事項(xiàng)為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);
}
}
}
}
以上都是我對(duì)別人的錯(cuò)誤代碼進(jìn)行的解析,下面我自己增加了一個(gè)方法用來(lái)增加的提醒事項(xiàng),因?yàn)槲抑恍枰砑犹嵝咽马?xiàng)部分,所以就只寫了調(diào)用提醒事項(xiàng),日歷等同,上面的代碼也實(shí)現(xiàn)了日歷的調(diào)用,只不過(guò)沒實(shí)現(xiàn)提醒事項(xiàng)的.其實(shí)我的這部分就是抽出來(lái)了增加提醒事項(xiàng)的部分,并增加了申請(qǐng)系統(tǒng)提醒事項(xiàng)權(quán)限的代碼,沒多少.
data就是提醒時(shí)間,可以任意比如:
NSDate*startData=[NSDate dateWithTimeIntervalSinceNow:10];
title是提醒內(nèi)容
-(void)addReminderNotify:(NSDate *)date title:(NSString *)title
{
//事件市場(chǎng)
EKEventStore *eventStore = [[EKEventStore alloc] init];
//6.0及以上通過(guò)下?面?方式寫?入事件
if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
//等待用戶是否同意授權(quán)日歷
//EKEntityMaskEvent提醒事項(xiàng)參數(shù)(該參數(shù)只能真機(jī)使用)? EKEntityTypeEvent日歷時(shí)間提醒參數(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)歷可以給別人一些小提示.??