三、提醒事件
提醒事件的用法和日历事件的用法基本一致,首先在Reminder应用中,每一个列表就是一个日历,下面代码示例了向列表中插入提醒事件的方法:
- (void)createNewReminder {
EKReminder *reminder = [EKReminder reminderWithEventStore:self.eventStore];
reminder.title = @"从应用创建的事件";
reminder.notes = @"备注";
for (EKCalendar *cal in [self.eventStore calendarsForEntityType:EKEntityTypeReminder]) {
if ([cal.title isEqualToString:@"自定义"]) {
reminder.calendar = cal;
}
}
//保存事件
NSError *error = nil;
[self.eventStore saveReminder:reminder commit:YES error:&error];
NSLog(@"%@", error);
}
同样,对应的也有Reminder的查询,删除等操作。
四、EKEventStore详解
EKEventStore类是EventKit中的核心类,用来对日历和提醒的事件进行操作。其中方法与属性列举如下:
@interface EKEventStore : NSObject
// 获取用户授权情况
+ (EKAuthorizationStatus)authorizationStatusForEntityType:(EKEntityType)entityType;
// 初始化方法
- (id)init;
// 使用指定的来源创建实例对象
- (instancetype)initWithSources:(NSArray<EKSource *> *)sources;
// 请求某个类型的事件访问权限
- (void)requestAccessToEntityType:(EKEntityType)entityType completion:(EKEventStoreRequestAccessCompletionHandler)completion;
// 唯一标识
@property(nonatomic, readonly) NSString *eventStoreIdentifier;
// 代理源 使用initWithSources方法实例化对应
@property (nonatomic, readonly) NSArray<EKSource *> *delegateSources;
// 可用的来源
@property (nonatomic, readonly) NSArray<EKSource *> *sources;
// 通过identifier获取指定的来源对象
- (nullable EKSource *)sourceWithIdentifier:(NSString *)identifier;
// 通过类型来获取所有的日历对象
- (NSArray<EKCalendar *> *)calendarsForEntityType:(EKEntityType)entityType;
// 获取默认的日历对象
@property(nullable, nonatomic, readonly) EKCalendar *defaultCalendarForNewEvents;
- (nullable EKCalendar *)defaultCalendarForNewReminders;
// 通过identifier获取日历对象
- (nullable EKCalendar *)calendarWithIdentifier:(NSString *)identifier;
// 添加一个新的日历,commit参数是都是否立刻提交修改
- (BOOL)saveCalendar:(EKCalendar *)calendar commit:(BOOL)commit error:(NSError **)error;
// 删除某个日历
- (BOOL)removeCalendar:(EKCalendar *)calendar commit:(BOOL)commit error:(NSError **)error;
// 根据identifier获取日程对象
- (nullable EKCalendarItem *)calendarItemWithIdentifier:(NSString *)identifier;
// 获取一组日程对象
- (NSArray<EKCalendarItem *> *)calendarItemsWithExternalIdentifier:(NSString *)externalIdentifier;
// 新建事件 span用来设置对于周期事件本次设置是否影响未来的事件
- (BOOL)saveEvent:(EKEvent *)event span:(EKSpan)span error:(NSError **)error;
- (BOOL)saveEvent:(EKEvent *)event span:(EKSpan)span commit:(BOOL)commit error:(NSError **)error;
// 移出事件
- (BOOL)removeEvent:(EKEvent *)event span:(EKSpan)span error:(NSError **)error;
- (BOOL)removeEvent:(EKEvent *)event span:(EKSpan)span commit:(BOOL)commit error:(NSError **)error;
// 通过identifier获取事件
- (nullable EKEvent *)eventWithIdentifier:(NSString *)identifier;
// 使用给定的NSPredicate进行事件查询
- (NSArray<EKEvent *> *)eventsMatchingPredicate:(NSPredicate *)predicate;
// 使用给定的NSPredicate进行事件枚举
- (void)enumerateEventsMatchingPredicate:(NSPredicate *)predicate usingBlock:(EKEventSearchCallback)block;
// 构造NSPredicate查询对象
- (NSPredicate *)predicateForEventsWithStartDate:(NSDate *)startDate endDate:(NSDate *)endDate calendars:(nullable NSArray<EKCalendar *> *)calendars;
// 提醒相关
// 新建一条提醒
- (BOOL)saveReminder:(EKReminder *)reminder commit:(BOOL)commit error:(NSError **)error;
// 删除提醒
- (BOOL)removeReminder:(EKReminder *)reminder commit:(BOOL)commit error:(NSError **)error;
// 进行提醒查询
- (id)fetchRemindersMatchingPredicate:(NSPredicate *)predicate completion:(void (^)(NSArray<EKReminder *> * __nullable reminders))completion;
// 取消某此查询
- (void)cancelFetchRequest:(id)fetchIdentifier;
// 构造查询对象
- (NSPredicate *)predicateForRemindersInCalendars:(nullable NSArray<EKCalendar *> *)calendars;
- (NSPredicate *)predicateForIncompleteRemindersWithDueDateStarting:(nullable NSDate *)startDate ending:(nullable NSDate *)endDate calendars:(nullable NSArray<EKCalendar *> *)calendars;
- (NSPredicate *)predicateForCompletedRemindersWithCompletionDateStarting:(nullable NSDate *)startDate ending:(nullable NSDate *)endDate calendars:(nullable NSArray<EKCalendar *> *)calendars;
// 将所有的修改一次性进行提交
- (BOOL)commit:(NSError **)error;
// 重置所有的修改
- (void)reset;
// 刷新来源
- (void)refreshSourcesIfNecessary;
@end
EKEntityType用来描述类型,定义如下:
typedef NS_ENUM(NSUInteger, EKEntityType) {
EKEntityTypeEvent, // 日历类型
EKEntityTypeReminder // 提醒类型
};
EKAuthorizationStatus用来描述用户授权状态:
typedef NS_ENUM(NSInteger, EKAuthorizationStatus) {
EKAuthorizationStatusNotDetermined = 0, // 用户尚未选择
EKAuthorizationStatusRestricted, // 应用无权访问
EKAuthorizationStatusDenied, // 用户拒绝授权
EKAuthorizationStatusAuthorized, // 用户授权
} ;
EKSpan用来描述所影响事件类型:
typedef NS_ENUM(NSInteger, EKSpan) {
EKSpanThisEvent, // 只影响本次事件
EKSpanFutureEvents // 对未来的事件也会产生影响
};
五、EKSource类详解
首先,EKSource描述了,例如某些日历是系统默认创建的,用户没有权限进行修改或删除,某些日历是用户自定义创建的,还有些可能来自云端,这个类继承自EKObject类,首先先看EKObject类的定义:
@interface EKObject : NSObject
// 数据对象是否有修改
@property (nonatomic, readonly) BOOL hasChanges;
// 是否是一个新的数据对象(为存储到日历或提醒中)
- (BOOL)isNew;
// 重置数据 将所有属性清空
- (void)reset;
// 回滚未提交的操作
- (void)rollback;
// 刷新数据
- (BOOL)refresh;
@end
EKSource是EKObject的子类,其中封装属性和方法如下:
@interface EKSource : EKObject
// 来源对象的ID 唯一标识
@property(nonatomic, readonly) NSString *sourceIdentifier;
// 来源对象的类型
@property(nonatomic, readonly) EKSourceType sourceType;
// 来源对象的标题
@property(nonatomic, readonly) NSString *title;
// 此来源对象中所包含的日历对象
@property(nonatomic, readonly) NSSet<EKCalendar *> *calendars;
// 获取此来源对象中某个类型的日历 (日历或提醒)
- (NSSet<EKCalendar *> *)calendarsForEntityType:(EKEntityType)entityType;
@end
EKSourceType枚举如下:
typedef NS_ENUM(NSInteger, EKSourceType) {
EKSourceTypeLocal, // 本地
EKSourceTypeExchange, // 交换
EKSourceTypeCalDAV, // CalDAV或iCloud
EKSourceTypeMobileMe, // MobileMe
EKSourceTypeSubscribed,// 订阅
EKSourceTypeBirthdays // 生日
};
六、EKCalendar类详解
EKCalendar是具体的日历对象,开发者可以对自定义的日历进行读写操作,其也是继承自EKObject对象,解析如下:
@interface EKCalendar : EKObject
// 通过制定的EKEventStore对象创建一个新的日历对象
+ (EKCalendar*)calendarWithEventStore:(EKEventStore *)eventStore;
// 创建某个类型的日历对象 (日历或提醒)
+ (EKCalendar *)calendarForEntityType:(EKEntityType)entityType eventStore:(EKEventStore *)eventStore;
// 当前日历对象所属于的来源
@property(null_unspecified, nonatomic, strong) EKSource *source;
// 日历对象的ID
@property(nonatomic, readonly) NSString *calendarIdentifier;
// 日历对象的标题 会在 日历 应用 或 提醒 应用中显示
@property(nonatomic, copy) NSString *title;
// 当前日历对象的类型
/*
typedef NS_ENUM(NSInteger, EKCalendarType) {
EKCalendarTypeLocal,
EKCalendarTypeCalDAV,
EKCalendarTypeExchange,
EKCalendarTypeSubscription,
EKCalendarTypeBirthday
};
*/
@property(nonatomic, readonly) EKCalendarType type;
// 当前日历是否支持编辑
@property(nonatomic, readonly) BOOL allowsContentModifications;
// 当前日历是否为订阅类型
@property(nonatomic, readonly, getter=isSubscribed) BOOL subscribed;
// 当前日历对象是否可变
@property(nonatomic, readonly, getter=isImmutable) BOOL immutable;
// 对应的提示颜色
@property(null_unspecified, nonatomic) CGColorRef CGColor;
// 支持的事件状态
/*
typedef NS_OPTIONS(NSUInteger, EKCalendarEventAvailabilityMask) {
EKCalendarEventAvailabilityNone = 0, // calendar doesn't support event availability
EKCalendarEventAvailabilityBusy = (1 << 0),
EKCalendarEventAvailabilityFree = (1 << 1),
EKCalendarEventAvailabilityTentative = (1 << 2),
EKCalendarEventAvailabilityUnavailable = (1 << 3),
};
*/
@property(nonatomic, readonly) EKCalendarEventAvailabilityMask supportedEventAvailabilities;
// 支持的日历类型
/*
typedef NS_OPTIONS(NSUInteger, EKEntityMask) {
EKEntityMaskEvent = (1 << EKEntityTypeEvent),
EKEntityMaskReminder = (1 << EKEntityTypeReminder)
};
*/
@property(nonatomic, readonly) EKEntityMask allowedEntityTypes;
@end