iOS實現(xiàn)日歷行程的增刪改查
前言
我們可以使用系統(tǒng)提供的EventKit框架來訪問和操作用戶的日歷日程和提醒(雖然日歷和提醒是兩個獨立的app,但是是用同一個框架來處理數(shù)據(jù))。同樣地,日歷和提醒的數(shù)據(jù)的數(shù)據(jù),都是存儲在同一個叫做Calendar Database的數(shù)據(jù)庫中:
EventKit不僅能獲取已存在的日程和提醒,還能在自己的app中創(chuàng)建、編輯、刪除用戶的日程和提醒,還能添加提醒、監(jiān)聽變化等。
在iOS10+中,若要訪問用戶日程或提醒,需要在info.plist中分別添加NSRemindersUsageDescription和NSCalendarsUsageDescription
一. 讀取日程
我們可以通過EKEventStore類來對用戶的Calendar database進(jìn)行查詢、創(chuàng)建、編輯、刪除等操作。我們可以使用條件來獲取符合條件的一組日程,也可以用唯一標(biāo)識來獲取指定的一條日程。獲取到的每一條日程都是一個EKEvent的實例對象,因此我們修改EKEvent對象的屬性即可實現(xiàn)修改日程信息。
1.創(chuàng)建連接
#import <EventKit/EventKit.h> ... EKEventStore *store = [[EKEventStore alloc] init];
EKEventStore對象的創(chuàng)建和釋放會比較耗時,因此我們一般會在app加載后只創(chuàng)建一個event store對象。
2.通過條件獲取日程
如果要獲取一個時間段內(nèi)的日程,可以使用EKEventStore對象的eventsMatchingPredicate: 方法。下面代碼演示如何獲取昨天至一年后的所有日程:
// 獲取日歷對象 NSCalendar *calendar = [NSCalendar currentCalendar]; // 創(chuàng)建開始時間 NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init]; oneDayAgoComponents.day = -1; NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents toDate:[NSDate date] options:0]; // 創(chuàng)建結(jié)束時間 NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init]; oneYearFromNowComponents.year = 1; NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents toDate:[NSDate date] options:0]; // 創(chuàng)建條件 NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo endDate:oneYearFromNow calendars:nil]; // 獲得符合條件的所有日程 NSArray *events = [store eventsMatchingPredicate:predicate];
3.批量處理日程
如果需要批量處理得到的日程,可以用EKEventStore
實例的enumerateEventsMatchingPredicate:usingBlock:方法(同步方法,為了不阻塞主線程建議在其它線程中執(zhí)行),例如打印出所有符合條件的日程標(biāo)題:
[store enumerateEventsMatchingPredicate:predicate usingBlock:^(EKEvent * _Nonnull event, BOOL * _Nonnull stop) { NSLog(@"event:%@",event.title); }];
4.通過唯一標(biāo)識獲取日程
每一個日程都有只讀的唯一標(biāo)識屬性eventIdentifier,我們可以通過EKEventStore對象的eventWithIdentifier:方法,傳入唯一標(biāo)識獲取指定的一個日程(這個標(biāo)識是只讀屬性,由系統(tǒng)指定,可以通過前面的條件查詢獲取,也可以在創(chuàng)建新的日程時保存這個唯一標(biāo)識),例如我們已經(jīng)知道一個日程的eventIdentifier值為”D8574A98-A929-4A92-8E9F-048F46FB5DE7:717c8b40-44e3-31ab-8243-2d5918e266ef”:
EKEvent *event = [store eventWithIdentifier:@"D8574A98-A929-4A92-8E9F-048F46FB5DE7:717c8b40-44e3-31ab-8243-2d5918e266ef"]; NSLog(@"event:%@",event);
二.創(chuàng)建日程
1.通過代碼創(chuàng)建
通過EKEvent對象的eventWithEventStore:來創(chuàng)建一個日程,并通過對應(yīng)的屬性編輯日程詳細(xì)信息,部分屬性如:
- title - 日程的標(biāo)題
- startDate - 日程的開始日期
- endDate - 日程的結(jié)束日期
- calendar - 日程對應(yīng)的日歷
- alarms - 日程的提醒時間
- recurrenceRules - 重復(fù)規(guī)則
實例代碼:
EKEvent *event = [EKEvent eventWithEventStore:store]; event.title = @"代碼創(chuàng)建的日程"; event.calendar = [store defaultCalendarForNewEvents]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [[NSDateComponents alloc] init]; components.hour = 1; NSDate *endTime = [calendar dateByAddingComponents:components toDate:[NSDate date] options:0]; event.startDate = [NSDate date]; event.endDate = endTime; event.notes = @"檔期詳情:hyaction://hunyu-music"; [event addAlarm:[EKAlarm alarmWithRelativeOffset:-10*60]]; NSError *error; [store saveEvent:event span:EKSpanFutureEvents commit:YES error:&error]; if (!error) { NSLog(@"添加成功!"); }else{ NSLog(@"添加失?。?@",error); }
2.通過系統(tǒng)日歷ui添加日程
#import <EventKitUI/EventKitUI.h> ... EKEventEditViewController *vc = [[EKEventEditViewController alloc] init]; vc.eventStore = store; vc.editViewDelegate = self; [self presentViewController:vc animated:YES completion:nil];
通過實現(xiàn)EKEventEditViewDelegate代理事件獲得結(jié)果:
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action{ NSLog(@"添加日程結(jié)果:%zd",action); [self dismissViewControllerAnimated:YES completion:nil]; }
三.編輯和刪除日程
我們可以通過修改event的屬性值來對日程進(jìn)行編輯,最后需要調(diào)用EKEventStore的實例方法saveEvent:span:commit:error:進(jìn)行持久化保存:
event.title = @"修改后的標(biāo)題"; NSError *error; [store saveEvent:event span:EKSpanFutureEvents commit:YES error:&error];
通過EKEventStore的實例方法removeEvent:span:commit:error:.來刪除日程:
NSError *error; [store removeEvent:event span:EKSpanFutureEvents error:&error];
四.添加提醒
我們可以給日程添加本地推送提醒,在指定的時間或地點給用戶進(jìn)行提醒。
1.基于時間的提醒
我們可以通過event的 addAlarm:方法為一個日程添加提醒。我們可以指定一個確切時間或一個相對時間(只能是日程開始時間之前)。通過removeAlarm: 方法可將提醒移除。
如在開始時間前10分鐘提醒:
[event addAlarm:[EKAlarm alarmWithRelativeOffset:-10*60]];
2.基于地理位置的提醒
我們可以設(shè)定當(dāng)用戶進(jìn)入或離開指定的地理位置區(qū)域時,觸發(fā)日程提醒。例如當(dāng)用戶離開公司,提醒用戶需要到超市購買日用品,作為開發(fā)者,需要確定一個經(jīng)緯度以及一個半徑范圍。
EKAlarm *alarm = [[EKAlarm alloc] init]; EKStructuredLocation *location = [EKStructuredLocation locationWithTitle:@"Current Location"]; location.geoLocation = [[CLLocation alloc] initWithLatitude:23.1754700000 longitude:113.4147400000]; alarm.structuredLocation = location; alarm.proximity = EKAlarmProximityEnter; [event addAlarm:alarm];
參考蘋果官方文檔
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS應(yīng)用運用設(shè)計模式中的Strategy策略模式的開發(fā)實例
這篇文章主要介紹了iOS應(yīng)用開發(fā)中對設(shè)計模式中的Strategy策略模式的運用,例子采用傳統(tǒng)的Objective-C語言代碼演示,需要的朋友可以參考下2016-03-03iOS ScrollView實現(xiàn)自動布局的方法(適用Swift 3.0 )
傳說中有一個美工ios開發(fā)者在遇到這個問題的時候特意跑到蘋果總部去咨詢?nèi)绾螌crollview進(jìn)行自動布局。當(dāng)然大家不用去了,下面這篇文章就來給大家介紹關(guān)于iOS ScrollView實現(xiàn)自動布局的方法,文中的語法同樣也適用Swift 3.0 ,需要的朋友可以參考下。2017-12-12Objective-C基礎(chǔ) 自定義對象歸檔詳解及簡單實例
這篇文章主要介紹了Objective-C基礎(chǔ) 自定義對象歸檔詳解及簡單實例的相關(guān)資料,需要的朋友可以參考下2017-04-04