오늘은 앱에서 디바이스 내 캘린더에 접근하고 일정을 확인 혹은 추가 , 삭제할 수 있는 방법에 대해서 알아보려고 한다.
먼저 그렇게 하기 위해서는 EventKit을 사용해야하는데 이 EventKit 프레임워크는 사람들이 앱에서 캘린더 항목을 만들고, 검색, 편집할 수 있도록 데이터에 대한 엑세스를 제공한다.
내가 어떤 앱을 만들었을때 캘린더 관련 기능을 사용하면서 디바이스 내 캘린더도 동시에 관리할 수 있게 되는 아주 아주 유용한 방식이니 한번 알아보자!
먼저 당연하게 이용자의 캘린더에 접근할 수 있는 권한이 필요하다. 그렇기 때문에 infoPlist로 들어가 다음과 같은 설정을 넣어주면 된다!
- Key : NSCalendarsUsageDescription
- Value : “앱에서 캘린더에 접근해 이벤트를 관리합니다”
이렇게 값을 넣어 주게 되면 해당 권한이 실행되는 시점에 이용자에게 캘린더 접근 권한에 대해 물어보고 권한을 설정할 수 있도록 설정이 완료된다.
그 다음엔 Manager를 구성해주면 된다. EventKit은 EKEventStore에 접근해 사용해야하기 때문에 해당 내용을 설정하고 권한 값과 가져온 이벤트 데이터를 담아줄 수 있는 인스턴스를 구성한다.
private let eventStore = EKEventStore()
@Published var events: [EKEvent] = []
@Published var authorizationStatus: EKAuthorizationStatus = .notDetermined
해당 내용을 설정한 다음 권한 설정을 요청하기 위한 메서드를 구현한다.
func checkCalendarAuthorizationStatus() {
authorizationStatus = EKEventStore.authorizationStatus(for: .event)
switch authorizationStatus {
case .notDetermined:
requestAccessToCalendar() // 아직 권한을 요청하지 않았으므로 권한 요청
case .authorized:
fetchEvents() // 이미 권한이 있으므로 이벤트 가져오기
case .denied, .restricted:
print("캘린더 접근 권한 거부")
@unknown default:
break
}
}
권한이 설정되지 않았을 때 권한을 요청하고 권한이 승인이 된다면 바로 데이터를 가져올 수 있도록 requestAccessToCalendar를 구현해주면 된다.
func requestAccessToCalendar() {
eventStore.requestAccess(to: .event) { [weak self] granted, error in
if granted {
DispatchQueue.main.async {
self?.fetchEvents() // 권한이 부여되었으므로 이벤트 가져오기
self?.authorizationStatus = .authorized
}
} else {
DispatchQueue.main.async {
self?.authorizationStatus = .denied // 권한이 거부됨
}
}
}
}
이렇게 구현하면 EventKit이 구현되는 곳에서 권한 설정을 물어보는 팝업을 띄우고 권한이 주어지면 바로 Event를 페치해올 수 있도록 한다.
권한이 설정되지 않으면 당연히 페치가 되지 않기 때문에 추가적으로 권한을 설정할 수 있도록 유도하는 로직을 구현하는게 좋다.
이제 권한 설정도 됐고 이벤트 데이터를 페치하면 되니까 해당 로직을 구현해보자
func fetchEvents() {
let startDate = Date() // 현재 날짜
if let endDate = Calendar.current.date(byAdding: .month, value: 1, to: startDate) { // 1달 뒤 날짜 설정
let predicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil)
let events = eventStore.events(matching: predicate)
DispatchQueue.main.async {
self.events = events // 이벤트 리스트를 events 프로퍼티에 저장
}
} else {
print("유효한 종료 날짜가 없습니다.")
}
}
이벤트 데이터를 가져올 날짜의 시작 날짜와 종료 날짜를 선택한 뒤 특정 캘린더만 가져오던지 혹은 모두 가져오던지 설정할 수 있다 모든 데이터를 가져오려면 calendar: nil로 설정해 가져온다.
그 다음 eventStore에 접근해 데이터를 가져와 넣어주면 구현이 완료된다.
여기까지 캘린더의 데이터를 가져오는 방식이 완료되었고 이제 데이터를 가져오는 건 구현했으니 캘린더에 이벤트를 추가하는 로직을 구현해보자
func addEvent(title: String, startDate: Date, endDate: Date) {
let event = EKEvent(eventStore: eventStore)
event.title = title // 이벤트 제목 설정
event.startDate = startDate // 이벤트 시작 시간
event.endDate = endDate // 이벤트 종료 시간
event.calendar = eventStore.defaultCalendarForNewEvents // 새 이벤트가 추가될 기본 캘린더
do {
try eventStore.save(event, span: .thisEvent) // 이벤트 저장
fetchEvents() // 저장 후 최신 이벤트 리스트 다시 가져오기
} catch {
print("이벤트 저장 오류")
}
}
EKEvent는 캘린더의 이벤트를 나타내는 클래스로 이 클래스의 속성인 (eventStore: )를 활용해 새로운 이벤트를 캘린더에 추가할 수 있다!
event의 제목 시작, 종료 등 일정의 정보를 넣어주고 defaultCalendarForNewEvents 를 설정해 새로운 이벤트가 설정될 기본 캘린더를 설정해준다. 그 이후 save(event, span: .tihsEvent를 활용해 캘린더에 해당 값을 저장하면 캘린더에서 추가하지 않아도 자동으로 일정이 추가되어있다!
다른 앱에서 캘린더 앱을 컨트롤할 수 있다는게 너무 신기하고 잘 활용하면 일정을 캘린더에서 추가하는게 아닌 인앱에서 해결할 수 있다는 점이 은근 사용할만한 기능이라고 생각했다.
오늘은 EvnetKit에 대해 알아보았다!!
'◽️ Programming > iOS' 카테고리의 다른 글
@AppStorage , UserDefaults의 특징 (0) | 2024.10.18 |
---|---|
앱 내 데이터 JSON으로 변환하기 (1) | 2024.10.14 |
Background Data Fetch 하기 (0) | 2024.10.08 |
SensorKit Data Fetch 하는 법 (0) | 2024.10.04 |
SensorKit을 구현하면서 만난 트러블 슈팅 ( 지속적으로 업데이트 예정 ) (1) | 2024.09.19 |