Programmatically add custom event in the iPhone Calendar
有没有办法从定制的应用程序将iCal事件添加到iPhone日历中?
根据苹果的文档,从iOS6.0开始,这一点已经发生了一些变化。
1)您应该通过"RequestAccessToEntityType:Completion:"请求访问用户日历,并在块内执行事件处理。
2)您需要立即提交事件或将"commit"参数传递给您的save/remove调用。
其他一切都保持不变…
将eventkit框架和
在我的示例中,我有一个nsstring*savedeventid实例属性。
要添加事件:
2删除事件:
1 2 3 4 5 6 7 8 9 | EKEventStore* store = [EKEventStore new]; [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (!granted) { return; } EKEvent* eventToRemove = [store eventWithIdentifier:self.savedEventId]; if (eventToRemove) { NSError* error = nil; [store removeEvent:eventToRemove span:EKSpanThisEvent commit:YES error:&error]; } }]; |
这会将事件添加到您的默认日历中,如果您有多个日历,那么您将发现哪一个是
斯威夫特版本
您需要导入EventKit框架
4添加事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let store = EKEventStore() store.requestAccessToEntityType(.Event) {(granted, error) in if !granted { return } var event = EKEvent(eventStore: store) event.title ="Event Title" event.startDate = NSDate() //today event.endDate = event.startDate.dateByAddingTimeInterval(60*60) //1 hour long meeting event.calendar = store.defaultCalendarForNewEvents do { try store.saveEvent(event, span: .ThisEvent, commit: true) self.savedEventId = event.eventIdentifier //save event id to access this particular event later } catch { // Display error to user } } |
移除事件
1 2 3 4 5 6 7 8 9 10 11 12 | let store = EKEventStore() store.requestAccessToEntityType(EKEntityTypeEvent) {(granted, error) in if !granted { return } let eventToRemove = store.eventWithIdentifier(self.savedEventId) if eventToRemove != nil { do { try store.removeEvent(eventToRemove, span: .ThisEvent, commit: true) } catch { // Display error to user } } } |
您可以使用OS 4.0中的事件工具包框架来完成此操作。
右键单击窗口左侧"组和文件导航器"中的"框架"组。选择"添加",然后选择"现有框架",然后选择"eventkit.framework"。
然后您应该能够添加具有如下代码的事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #import"EventTestViewController.h" #import <EventKit/EventKit.h> @implementation EventTestViewController - (void)viewDidLoad { [super viewDidLoad]; EKEventStore *eventStore = [[EKEventStore alloc] init]; EKEvent *event = [EKEvent eventWithEventStore:eventStore]; event.title = @"EVENT TITLE"; event.startDate = [[NSDate alloc] init]; event.endDate = [[NSDate alloc] initWithTimeInterval:600 sinceDate:event.startDate]; [event setCalendar:[eventStore defaultCalendarForNewEvents]]; NSError *err; [eventStore saveEvent:event span:EKSpanThisEvent error:&err]; } @end |
是的,这个(2.1)仍然没有API。但在WWDC,似乎已经有很多人对功能感兴趣(包括我自己),建议您访问下面的站点并为此创建一个功能请求。如果有足够的兴趣,他们可能最终会将ical.framework移动到公共SDK。
https://developer.apple.com/bugreporter/
iPhone OS 4.0中添加了日历访问:
0Swift 4.0实施:
使用
然后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @IBAction func addtoCalendarClicked(sender: AnyObject) { let eventStore = EKEventStore() eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in if (granted) && (error == nil) { print("granted \(granted)") print("error \(error)") let event = EKEvent(eventStore: eventStore) event.title ="Event Title" event.startDate = Date() event.endDate = Date() event.notes ="Event Details Here" event.calendar = eventStore.defaultCalendarForNewEvents var event_id ="" do { try eventStore.save(event, span: .thisEvent) event_id = event.eventIdentifier } catch let error as NSError { print("json error: \(error.localizedDescription)") } if(event_id !=""){ print("event added !") } } }) } |
您可以使用Tristan概述的事件API添加事件,也可以添加显示在iOS日历中的Google日历事件。
使用谷歌的API Objective-C客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | - (void)addAnEvent { // Make a new event, and show it to the user to edit GTLCalendarEvent *newEvent = [GTLCalendarEvent object]; newEvent.summary = @"Sample Added Event"; newEvent.descriptionProperty = @"Description of sample added event"; // We'll set the start time to now, and the end time to an hour from now, // with a reminder 10 minutes before NSDate *anHourFromNow = [NSDate dateWithTimeIntervalSinceNow:60*60]; GTLDateTime *startDateTime = [GTLDateTime dateTimeWithDate:[NSDate date] timeZone:[NSTimeZone systemTimeZone]]; GTLDateTime *endDateTime = [GTLDateTime dateTimeWithDate:anHourFromNow timeZone:[NSTimeZone systemTimeZone]]; newEvent.start = [GTLCalendarEventDateTime object]; newEvent.start.dateTime = startDateTime; newEvent.end = [GTLCalendarEventDateTime object]; newEvent.end.dateTime = endDateTime; GTLCalendarEventReminder *reminder = [GTLCalendarEventReminder object]; reminder.minutes = [NSNumber numberWithInteger:10]; reminder.method = @"email"; newEvent.reminders = [GTLCalendarEventReminders object]; newEvent.reminders.overrides = [NSArray arrayWithObject:reminder]; newEvent.reminders.useDefault = [NSNumber numberWithBool:NO]; // Display the event edit dialog EditEventWindowController *controller = [[[EditEventWindowController alloc] init] autorelease]; [controller runModalForWindow:[self window] event:newEvent completionHandler:^(NSInteger returnCode, GTLCalendarEvent *event) { // Callback if (returnCode == NSOKButton) { [self addEvent:event]; } }]; } |
dashrath答案的swift 4更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import UIKit import EventKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let eventStore = EKEventStore() eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in if (granted) && (error == nil) { let event = EKEvent(eventStore: eventStore) event.title ="My Event" event.startDate = Date(timeIntervalSinceNow: TimeInterval()) event.endDate = Date(timeIntervalSinceNow: TimeInterval()) event.notes ="Yeah!!!" event.calendar = eventStore.defaultCalendarForNewEvents var event_id ="" do{ try eventStore.save(event, span: .thisEvent) event_id = event.eventIdentifier } catch let error as NSError { print("json error: \(error.localizedDescription)") } if(event_id !=""){ print("event added !") } } }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
也不要忘记添加日历使用权限
SWIFT-4.2中的工作代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import UIKit import EventKit import EventKitUI class yourViewController: UIViewController{ let eventStore = EKEventStore() func addEventToCalendar() { eventStore.requestAccess( to: EKEntityType.event, completion:{(granted, error) in DispatchQueue.main.async { if (granted) && (error == nil) { let event = EKEvent(eventStore: self.eventStore) event.title = self.headerDescription event.startDate = self.parse(self.requestDetails.value(forKey:"session_time") as? String ??"") event.endDate = self.parse(self.requestDetails.value(forKey:"session_end_time") as? String ??"") let eventController = EKEventEditViewController() eventController.event = event eventController.eventStore = self.eventStore eventController.editViewDelegate = self self.present(eventController, animated: true, completion: nil) } } }) } } |
现在我们将看到事件屏幕,您还可以在这里修改设置:
现在添加委托方法来处理取消并添加事件屏幕的事件按钮操作:
1 2 3 4 5 6 7 | extension viewController: EKEventEditViewDelegate { func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) { controller.dismiss(animated: true, completion: nil) } } |
注意:不要忘记在信息列表中添加nscalendarsusagedescription键。
记住,要将结束日期设置为已创建事件,它是必需的。
否则,它将失败(几乎是无声的),并出现此错误:
1 | "Error Domain=EKErrorDomain Code=3"No end date has been set." UserInfo={NSLocalizedDescription=No end date has been set.}" |
我的完整工作代码是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | EKEventStore *store = [EKEventStore new]; [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (!granted) { return; } EKEvent *calendarEvent = [EKEvent eventWithEventStore:store]; calendarEvent.title = [NSString stringWithFormat:@"CEmprendedor: %@", _event.name]; calendarEvent.startDate = _event.date; // 5 hours of duration, we must add the duration of the event to the API NSDate *endDate = [_event.date dateByAddingTimeInterval:60*60*5]; calendarEvent.endDate = endDate; calendarEvent.calendar = [store defaultCalendarForNewEvents]; NSError *err = nil; [store saveEvent:calendarEvent span:EKSpanThisEvent commit:YES error:&err]; self.savedEventId = calendarEvent.eventIdentifier; //saving the calendar event id to possibly deleted them }]; |
简单…使用Tapku库…你可以用谷歌搜索这个词并使用它…它的开源…享受…不需要窃听那些代码……
谷歌的想法不错,但也有问题。
我可以成功地打开一个谷歌日历事件屏幕-但只在主桌面版本上,它不能在iPhone Safari上正确显示。谷歌移动日历(google mobile calendar)确实在Safari上显示得很好,但似乎无法与API一起添加事件。
目前,我看不出有什么好办法可以摆脱这个困境。