Lập trình thêm sự kiện tùy chỉnh trong Lịch iPhone


Câu trả lời:


166

Dựa trên Tài liệu của Apple , điều này đã thay đổi một chút kể từ iOS 6.0.

1) Bạn nên yêu cầu quyền truy cập vào lịch của người dùng thông qua "requestAccessToEntityType: hoàn thành:" và thực hiện xử lý sự kiện bên trong một khối.

2) Bạn cần phải cam kết sự kiện của mình ngay bây giờ hoặc chuyển thông số "cam kết" vào cuộc gọi lưu / xóa của bạn

Mọi thứ khác vẫn giữ nguyên ...

Thêm khung EventKit và #import <EventKit/EventKit.h>mã của bạn.

Trong ví dụ của tôi, tôi có một thuộc tính đối tượng NSString * yetEventId.

Để thêm một sự kiện:

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

Xóa sự kiện:

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

Điều này sẽ thêm các sự kiện vào lịch mặc định của bạn, nếu bạn có nhiều lịch thì bạn sẽ tìm ra sự kiện nào

Phiên bản Swift

Bạn cần nhập khung EventKit

import EventKit

Thêm sự kiện

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

Xóa sự kiện

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
không hoạt động với tôi, mọi thứ đều không có lỗi nhưng không có sự kiện nào trong lịch
Boris Gafurov

Mọi thứ được lưu trữ trong đối tượng ekevent nhưng không lưu trữ bên trong lịch hlp me

1
@William T: Tôi có thể trình bày màn hình Thêm sự kiện của ứng dụng Lịch (sử dụng Lược đồ URL) và chuyển thông tin của sự kiện để khi màn hình Thêm sự kiện xuất hiện, nó sẽ có dữ liệu được điền trước. Người dùng chỉ cần nhấn nút thêm sự kiện. Trong sự kiện ví dụ của bạn được thêm mà không có bất kỳ dấu hiệu nào cho người dùng.
Ans

1
nếu tất cả dường như hoạt động nhưng không có lịch nào xuất hiện, hãy kiểm tra xem liệu lịch của Cloud VS Local có phải là vấn đề không. Nếu bạn có kết hợp Lịch đám mây và Lịch địa phương, Lịch đám mây có thể buộc lịch địa phương bị ẩn.
zonabi

2
@ReddyBasha khi bạn thêm sự kiện, bạn cần lưu lại eventIdentifier và lưu trữ nó để sử dụng trong tương lai. Bạn nên sử dụng id sự kiện đó khi bạn xóa nó.
William T.

154

Bạn có thể làm điều này bằng cách sử dụng khung Bộ công cụ sự kiện trong HĐH 4.0.

Nhấp chuột phải vào nhóm FrameWorks trong Nhóm và Trình điều hướng tệp ở bên trái cửa sổ. Chọn 'Thêm' rồi 'Khung hình hiện tại' rồi 'EventKit.Framework'.

Sau đó, bạn sẽ có thể thêm các sự kiện với mã như thế này:

#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
Cảm ơn đã đăng bài này. Chỉ là một lời nhắc nhở cho tất cả những người đọc điều này: hãy cẩn thận để xem rò rỉ bộ nhớ. Có một cặp vợ chồng trong mẫu mã này. Ngoài ra, các thực tiễn tốt nhất sẽ ra lệnh rằng bạn kiểm tra giá trị của 'err' sau saveEvent: span: error và xử lý mọi thứ tương ứng.
David Carney

Bạn có biết làm thế nào để thêm sự kiện tái phát? như một sự kiện cho mỗi thứ hai?
Jay Vachhani

5
Thêm sự kiện lặp lại theo chương trình: kiểm tra xem nhà phát triển này.apple.com / l Library / ios / # ocumentation / EventKit / trên . Một tùy chọn khác là sử dụng các bộ điều khiển xem khung cung cấp mặc định để thêm / chỉnh sửa các sự kiện (như ứng dụng Lịch At-A-Glance bit.ly/cJq4Bh ). Đối với tùy chọn này, hãy xem developer.apple.com/l
Library / ios /#documentation / EventKitUI / từ

Để thêm các khung trong XCode 4, hãy xem câu hỏi SO này: stackoverflow.com/questions/3352664/ Đổi
Nate

1
4.0? sẽ không bay trong 6 câu trả lời ở trên
Boris Gafurov

13

Có, vẫn không có API cho việc này (2.1). Nhưng có vẻ như tại WWDC, rất nhiều người đã quan tâm đến chức năng (bao gồm cả bản thân tôi) và đề xuất là vào trang web bên dưới và tạo một yêu cầu tính năng cho việc này. Nếu có đủ sự quan tâm, cuối cùng họ có thể chuyển ICal.framework sang SDK công khai.

https://developer.apple.com/ormsreporter/


5
câu trả lời đã lỗi thời, hãy cân nhắc để loại bỏ điều này
Jasper


5

Bạn có thể thêm sự kiện bằng API sự kiện như Tristan đã nêu và bạn cũng có thể thêm sự kiện Lịch Google hiển thị trong lịch iOS.

sử dụng Máy khách API Objective-C của Google

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

Triển khai Swift 4.0:

sử dụng nhập vào đầu trang bởi import EventKit

sau đó

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

bạn có thể giúp tôi với lịch google về câu trả lời tương tự @Dashrath
Dilip Tiwari

4

Cập nhật cho swift 4 cho câu trả lời Dashrath

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


}

cũng đừng quên thêm quyền cho sử dụng lịch hình ảnh cho thiết lập riêng tư


2

Mã làm việc trong 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)

            }
        }


       })
    }

}

Bây giờ chúng tôi sẽ có màn hình sự kiện và tại đây bạn cũng có thể sửa đổi cài đặt của mình:

nhập mô tả hình ảnh ở đây

Bây giờ thêm phương thức ủy nhiệm để xử lý Hủy và thêm hành động nút sự kiện của màn hình sự kiện:

    extension viewController: EKEventEditViewDelegate {

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

    }
}

Lưu ý: Đừng quên thêm khóa NSCalendarsUsageDes mô tả vào thông tin.


1

Hãy nhớ đặt endDate cho sự kiện đã tạo, nó là bắt buộc.

Nếu không, nó sẽ thất bại (gần như âm thầm) với lỗi này:

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

Mã làm việc hoàn chỉnh cho tôi là:

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
Và cũng nên nhớ rằng ngày kết thúc phải bằng hoặc lớn hơn ngày bắt đầu. Nếu không, bạn sẽ nhận được một lỗi khác.
ủ rũ

0

Ý tưởng của Google là một ý tưởng hay, nhưng có vấn đề.

Tôi có thể mở thành công màn hình sự kiện lịch Google - nhưng chỉ trên phiên bản máy tính để bàn chính và nó không hiển thị đúng trên iPhone Safari. Lịch trên thiết bị di động của Google, hiển thị đúng trên Safari, dường như không hoạt động với API để thêm các sự kiện.

Hiện tại, tôi không thể thấy một cách tốt để thoát khỏi cái này.


0

Đơn giản .... sử dụng thư viện tapku .... bạn có thể google từ đó và sử dụng nó ... nguồn mở của nó ... tận hưởng ..... không cần phải làm phiền với các mã đó ....



Lịch thư viện Tapku có thể đồng bộ hóa với các sự kiện ứng dụng lịch
coder1010

Tất cả những gì tôi biết là thư viện Tapku là một điều khiển thành phần lịch có một tùy chọn gọi là Nguồn dữ liệu. Vì vậy, logic của bạn là viết ra nguồn mà bạn đang tìm nạp từ ... Mã hóa hạnh phúc :)
Rajesh_Bangalore
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.