프로그래밍 방식으로 iPhone 캘린더에 커스텀 이벤트 추가


181

커스텀 앱에서 iCal 이벤트를 iPhone 캘린더에 추가하는 방법이 있습니까?

답변:


166

를 기반으로 애플 문서 , 이것은 아이폰 OS 6.0로 약간 변경되었습니다.

1) "requestAccessToEntityType : completion :"을 통해 사용자 캘린더에 대한 액세스를 요청하고 블록 내에서 이벤트 처리를 실행해야합니다.

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

6
나를 위해 작동하지 않는, 모든 오류 O /하지만 달력 어떠한 경우 승 간다
보리스 Gafurov

모든 것은 ekevent 객체에 저장되지만 달력 안에 저장되지 않습니다

1
@William T : 캘린더 앱의 이벤트 추가 화면 (URL 체계 사용)을 표시하고 이벤트 정보를 전달하여 이벤트 추가 화면이 나타날 때 미리 채워진 데이터를 가질 수 있습니까? 사용자는 이벤트 추가 버튼을 누르면됩니다. 귀하의 예에서 이벤트는 사용자에게 표시되지 않고 추가되었습니다.
Ans

1
모두 작동하지만 캘린더가 나타나지 않으면 Cloud VS Local 캘린더가 문제인지 확인하십시오. 클라우드 및 로컬 캘린더가 혼합되어있는 경우 클라우드 캘린더는 로컬 캘린더를 강제로 숨길 수 있습니다.
zonabi 2016 년

2
@ReddyBasha 이벤트를 추가 할 때 eventIdentifier를 저장하고 나중에 사용하기 위해 저장해야합니다. 해당 이벤트 ID를 제거 할 때 사용해야합니다.
William T.

154

OS 4.0에서 이벤트 키트 프레임 워크를 사용하여이를 수행 할 수 있습니다.

창의 왼쪽에있는 그룹 및 파일 네비게이터에서 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

18
이것을 게시 해 주셔서 감사합니다. 이 글을 읽는 모든 사람들에게 알림 : 메모리 누수를 조심하십시오. 이 코드 샘플에는 몇 가지가 있습니다. 또한 모범 사례는 saveEvent : span : error 후에 'err'값을 확인하고 그에 따라 처리하도록 지시합니다.
David Carney

반복 이벤트를 추가하는 방법을 알고 있습니까? 매주 월요일 이벤트처럼?
Jay Vachhani

5
프로그래밍 방식으로 반복 이벤트 추가 : developer.apple.com/library/ios/#documentation/EventKit/…를 확인하십시오 . 다른 옵션은 이벤트를 추가 / 편집하는 데 기본 프레임 워크 제공보기 컨트롤러를 사용하는 것입니다 (예 : Calendar At-A-Glance 앱 bit.ly/cJq4Bh ). 이 옵션에 대해서는 developer.apple.com/library/ios/#documentation/EventKitUI/…를
DenTheMan

XCode 4에 프레임 워크를 추가하려면 다음 SO 질문을 참조하십시오 : stackoverflow.com/questions/3352664/…
Nate

1
4.0? 하지 대답 위의 6 참조 비행거야
보리스 Gafurov

13

예, 여전히이 API (2.1)가 없습니다. 그러나 WWDC에서는 많은 사람들이 이미 기능에 관심을 보였으며 (자신 포함) 아래 사이트로 이동하여 기능 요청을 작성하는 것이 좋습니다. 관심이 충분하면 ICal.framework를 공개 SDK로 옮길 수 있습니다.

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


5
답변이 오래되었습니다, 이것을 제거하는 것을 고려하십시오
Jasper


5

Tristan 개요와 같은 이벤트 API를 사용하여 이벤트를 추가 할 수 있으며 iOS 캘린더에 표시되는 Google 캘린더 이벤트를 추가 할 수도 있습니다.

사용하는 구글의 API 목표 - 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];
                }
              }];
}

5

스위프트 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 !")
            }
        }
    })
}

같은 답변에 관한 Google 캘린더로 나를 도울 수 있습니까
Dilip Tiwari

4

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


}

또한 캘린더 사용 권한을 추가하는 것을 잊지 마십시오 개인 설정 용 이미지


2

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)

            }
        }


       })
    }

}

이제 이벤트 화면이 표시되며 설정을 수정할 수도 있습니다.

여기에 이미지 설명을 입력하십시오

이제 취소를 처리 할 대리자 메서드를 추가하고 이벤트 화면의 이벤트 단추 동작을 추가하십시오.

    extension viewController: EKEventEditViewDelegate {

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

    }
}

참고 : 정보 plist에 NSCalendarsUsageDescription 키 를 추가하는 것을 잊지 마십시오 .


1

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

1
또한 종료 날짜는 시작 날짜와 같거나 커야합니다. 그렇지 않으면 다른 오류가 발생합니다.
moody

0

Google 아이디어는 좋지만 문제가 있습니다.

Google 캘린더 일정 화면을 열 수 있지만 기본 데스크톱 버전에서만 가능하며 iPhone Safari에는 제대로 표시되지 않습니다. Safari에 제대로 표시되는 Google 모바일 캘린더가 API와 함께 작동하여 이벤트를 추가하지 않는 것 같습니다.

현재로서는 이것에서 좋은 방법을 볼 수 없습니다.


0

간단합니다 .... tapku 라이브러리를 사용하십시오. ... 당신은 그 단어를 구글하고 그것을 사용할 수 있습니다 ... 그것의 오픈 소스 ... 즐기십시오 ..... 그 코드로 버그를 할 필요가 없습니다 ....



Tapku 라이브러리 캘린더가 캘린더 앱 이벤트와 동기화 가능
coder1010

내가 아는 것은 Tapku 라이브러리가 데이터 소스라는 옵션이있는 달력 구성 요소 컨트롤이라는 것입니다. 따라서 소스에서 가져 오는 소스를 작성하는 논리까지 ... Happy Coding :)
Rajesh_Bangalore
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.