以编程方式在 iPhone 日历中添加自定义事件

有没有办法从自定义应用程序中将 iCal 事件添加到 iPhone 日历中?

143124 次浏览

是的,仍然没有这方面的 API (2.1)。但是在 WWDC 似乎已经有很多人对这个功能感兴趣了(包括我自己) ,建议去下面的网站,为这个功能创建一个特性请求。如果有足够的兴趣,他们可能最终会将 ICal.Framework 移动到公共 SDK。

Https://developer.apple.com/bugreporter/

谷歌的想法是一个不错的想法,但存在一些问题。

我可以成功地打开谷歌日历事件界面——但只能在主桌面版本上,而且在 iPhone Safari 上显示不正确。在 Safari 上显示正确的 Google 移动日历,似乎不能与 API 一起添加事件。

目前,我看不出有什么好办法。

您可以使用 OS 4.0中的 Event Kit 框架来实现这一点。

右键单击窗口左侧“组和文件导航器”中的 FrameWorks 组。选择’添加’,然后’现有框架’,然后’事件工具包。框架’。

然后,您应该能够使用以下代码添加事件:

#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

您可以使用类似 Tristan 概述的 Event API 添加事件,也可以添加显示在 iOS 日历中的 Google Calendar 事件。

使用 Google 的 API Objective-C 客户端

  - (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];
}
}];
}

很简单。使用塔布库图书馆... 。你可以谷歌这个词,并使用它... 它的开源... 享受... ..。不需要窃听那些代码..。

基于 苹果文档,这在 iOS 6.0上发生了一些变化。

1)您应该通过“ requestAccessToEntityType: complete:”请求访问用户的日历,并在块内执行事件处理。

2)你需要立即提交你的事件,或者将“提交”参数传递给你的保存/删除调用

其他一切都保持不变。

将 EventKit 框架和 #import <EventKit/EventKit.h>添加到代码中。

在我的示例中,我有一个 NSString * savedEventId 实例属性。

添加事件:

    EKEventStore *store = [EKEventStore new];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (!granted) { return; }
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = @"Event Title";
event.startDate = [NSDate date]; //today
event.endDate = [event.startDate dateByAddingTimeInterval:60*60];  //set 1 hour meeting
event.calendar = [store defaultCalendarForNewEvents];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
self.savedEventId = event.eventIdentifier;  //save the event id if you want to access this later
}];

删除事件:

    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 框架

import EventKit

添加事件

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
}
}

删除事件

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
}
}
}

Swift 4.0的实现:

通过 import EventKit在页面顶部使用导入

那么

@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 !")
}
}
})
}

请记住将 endDate 设置为创建的事件,这是强制性的。

否则,它会以这个错误失败(几乎是无声的) :

"Error Domain=EKErrorDomain Code=3 "No end date has been set." UserInfo={NSLocalizedDescription=No end date has been set.}"

对我来说,完整的工作代码是:

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
}];

Dashrath 答案更新为迅捷4

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.
}




}

也不要忘记添加日历使用权限 image for privary setting

Swift-4.2中的工作代码

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)


}
}




})
}


}

现在我们将看到事件界面,在这里你也可以修改你的设置:

enter image description here

现在添加委托方法来处理 Cancel 并添加事件屏幕的事件按钮操作:

    extension viewController: EKEventEditViewDelegate {


func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
controller.dismiss(animated: true, completion: nil)


}
}

注意: 不要忘记在信息列表中添加 NSCalendarsUsageDescription键。