代码之家  ›  专栏  ›  技术社区  ›  Vadim

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

  •  177
  • Vadim  · 技术社区  · 16 年前

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

    11 回复  |  直到 6 年前
        1
  •  161
  •   William T.    9 年前

    基于 Apple Documentation 从iOS 6.0开始,这已经有了一些变化。

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

    2)您需要立即提交事件或将“commit”参数传递给您的save/remove调用。

    其他一切都保持不变…

    添加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
            }
        }
    }
    
        2
  •  154
  •   Piotr Byzia    12 年前

    您可以使用OS 4.0中的事件工具包框架来完成此操作。

    右键单击窗口左侧“组和文件导航器”中的“框架”组。选择“添加”,然后选择“现有框架”,然后选择“eventkit.framework”。

    然后您应该能够添加具有如下代码的事件:

    #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
    
        3
  •  13
  •   keremk    16 年前

    是的,这个(2.1)仍然没有API。但在WWDC,似乎已经有很多人对功能感兴趣(包括我自己),建议您访问下面的站点并为此创建一个功能请求。如果有足够的兴趣,他们可能最终会将ical.framework移动到公共SDK。

    https://developer.apple.com/bugreporter/

        4
  •  12
  •   Chris S    15 年前

    Calendar access is being added in iPhone OS 4.0 :

    日历访问
    应用程序现在可以直接在 带有活动工具包的日历应用程序。
    创建定期事件,设置开始和结束 时间并分配给任何日历 在设备上。

        5
  •  5
  •   Iggy    12 年前

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

    使用 Google's API Objective-C Client

      - (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];
                    }
                  }];
    }
    
        6
  •  4
  •   luhuiya    7 年前

    dashrath答案的swift 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

        7
  •  4
  •   Axel Guilmin Forrest Porter    7 年前

    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 !")
                }
            }
        })
    }
    
        8
  •  1
  •   Rajesh_Bangalore    12 年前

    简单…使用Tapku库…你可以用谷歌搜索这个词并使用它…它的开源…享受…不需要窃听那些代码……

        9
  •  1
  •   halbano    8 年前

    记住,要将结束日期设置为已创建事件,它是必需的。

    否则,它将失败(几乎是无声的),并出现此错误:

    "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
    }];
    
        10
  •  0
  •   xgretsch    15 年前

    谷歌的想法不错,但也有问题。

    我可以成功地打开一个谷歌日历事件屏幕-但只在主桌面版本上,它不能在iPhone Safari上正确显示。谷歌移动日历(google mobile calendar)确实在Safari上显示得很好,但似乎无法与API一起添加事件。

    目前,我看不出有什么好办法可以摆脱这个困境。

        11
  •  0
  •   Alok    6 年前

    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

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

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

    注: 别忘了添加 nscalendars用法说明 输入信息列表。