감자주먹밥

[IOS] EventKit 달력, 미리알림 이벤트 관리 본문

IOS/UIKit

[IOS] EventKit 달력, 미리알림 이벤트 관리

JustHm 2023. 4. 5. 18:57
728x90

EventKit

달력, 미리알림 어플의 데이터에 접근 하여 이벤트를 생성, 검색, 편집을 할 수 있는 프레임워크.

먼저 사용하기 전, info.plist에 권한 체크를 받아야 한다.

let status = EKEventStore.authorizationStatus(for: .event)
switch status {
case .notDetermined: //아직 권한 팝업 뜨기 전
    let accessGranted = try await ekStore.requestAccess(to: .event)
    guard accessGranted else {
        throw ServiceError.accessDenied
    }
case .restricted:
    throw ServiceError.accessRestricted
case .denied: //권한 거부
    throw ServiceError.accessDenied
case .authorized: //권한 허용
    return
@unknown default:
    throw ServiceError.unknown
}

EKEventStore.authorizationStatus(for:) 메서드를 사용해 권한 체크 여부를 확인 할 수 있다.

for 파라미터는 EKEntityType으로 .event, .reminder가 존재하고 각각 달력, 미리알림의 권한 상태를 확인할 수 있다.

아직 권한상태를 받지 않았다면 EKEventStore의 requestAccess 메서드로 다시 한 번 권한허용 alert를 띄울 수 있다.

EventKit 사용

EKEventStore를 사용해 저장, 삭제, 조회가 가능하다.

이벤트 저장

let calendars = ekStore.calendars(for: .event)
let event = EKEvent(eventStore: ekStore)
//캘린더에 저장할 이벤트 설정
for calendar in calendars {
    if calendar.title == "집" {
        let reminder1 = EKAlarm(relativeOffset: 0)// 해당 시간이 되면 알람 울림!
        event.calendar = calendar
        event.title = title
        event.startDate = startDate
        event.endDate = endDate
        event.alarms = [reminder1]
        break
    }
}
//캘린더에 저장
do {
	try ekStore.save(event, span: .thisEvent, commit: true)
} catch {
    throw ServiceError.storeError
}

calendars 메서드를 사용해 달력의 태그를 전부 가져온다 (달력 태그는 이벤트 불러오기에 설명)

EKEvent 객체를 생성해 태그가 일치하는 달력의 정보를 event에 넣고 나머지 제목, 날짜, 알림 정보를 주입한다.

EKEventStore의 save 메서드를 사용해 정의한 이벤트를 저장할 수 있다.

미리알림의 경우도 비슷하다. EKReminder 객체를 생성해 정의하고  calendar에 store.defaultCalendarForNewReminders() 만 넣으면 미리알림에 저장할 수 있다.

이벤트 삭제

try ekStore.remove(ekReminder, commit: true)

이벤트 삭제는 EKEventStore객체의 remove 메서드를 사용해 지울 수 있다.

remove 메서드는 여러개가 있는데 각각 EKEvent와 EKReminder 객체를 받아 지울 수 있다.

이벤트를 가져오는 방법은 아래에 설명

이벤트 불러오기

let ekStore = EKEventStore()
// 미리알림
let predicate = ekStore.predicateForReminders(in: nil)
let ekReminders = try await ekStore.reminders(matching: predicate)

// 달력
let predicate = ekStore.predicateForEvents(withStart: startDate,
                                           end: endDate,
                                           calendars: ekStore.calendars(for: .event))
let events = ekStore.events(matching: predicate)

미리 알림, 달력에서 이벤트를 가져오는 것은 비슷하다. predicateFor~~() 메서드를 통해 조회를 위한 NSPredicate를 받아 EKEventStore에 event나 reminders 메서드에 matching 파라미터로 넣어주면 이벤트들을 받아올 수 있다.

미리알림은 EKReminder, 달력은 EKEvent로 이벤트들을 받을 수 있다.

달력의 경우 시작~끝 날짜에 있는 정보를 가져올 수 있고, calednars 파라미터는 [EKCalendar] 타입으로 달력앱에 지정된 태그의 이벤트만 받아올 수 있다. 위처럼 그냥 EKEventStore에 calendars(for: .event) 메서드를 사용하면 모든 태그의 이벤트를 가져올 수 있다.

*nil을 넣어도 모든 태그의 이벤트를 가져온다.

ekStore.calendarItem(withIdentifier:)

calendarItem 에 identifier를 넣으면 개별로 이벤트를 받아 올 수도 있다.

EKCalendarItem optional 타입이 반환되는데 EKCalendarItem은 EKEvent, EKReminder의 상위 클래스로 가져올 때 캐스팅 하여 가져와도 된다.

728x90
Comments