스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
캘린더 및 EventKit 알아보기
캘린더를 앱에 불러와서 사람들이 시간을 더 잘 관리할 수 있도록 돕는 방법을 알아보세요. 앱에서 새 이벤트를 만들고, 이벤트를 불러오고, 가상 회의 확장 기능을 구현하는 방법을 알려드립니다. 또한 다른 사람의 캘린더 데이터의 개인정보를 침해하지 않으면서도 앱의 연결성을 유지하는 데 도움이 되는 몇 가지 캘린더 접근 권한 변경 사항도 안내해 드립니다.
챕터
- 0:41 - Integrate with Calendar
- 1:52 - Frameworks overview
- 4:36 - Adding events
- 4:56 - Adding: EventKitUI
- 8:07 - Adding: Siri Event Suggestions
- 10:59 - Adding: Write-only
- 12:16 - Adding: EventKit
- 14:23 - Full Access
- 18:01 - Virtual conferences
리소스
- Accessing Calendar using EventKit and EventKitUI
- EventKit
- Explore the Human Interface Guidelines for privacy
- Siri Event Suggestions
- Universal Links for Developers
관련 비디오
WWDC23
WWDC20
-
다운로드
♪ ♪
안녕하세요, 저는 애덤입니다 이 영상에서는 앱이 캘린더 및 EventKit로 사람들의 시간 관리를 돕는 방법을 다룹니다 먼저 앱과 캘린더를 통합하는 몇 가지 방법을 살펴보고 관련된 프레임워크의 개요를 보여드린 다음 몇 가지 구체적인 예제를 살펴보겠습니다 이러한 프레임워크로 다음과 같은 보편적인 기능을 구현해 보는 거죠 이벤트 추가, 전체 접근 권한으로 이벤트 가져오기 가상 회의 확장 프로그램 구현하기 같은 것들요
사람들은 캘린더에 의존하여 시간을 관리하고 미래를 계획하지만 캘린더는 하나의 앱 이상입니다 캘린더와 통합하면 앱이 다양한 역할을 수행할 수 있으며 이러한 다양한 역할을 함께 사용하면 더 풍부한 캘린더 경험을 제공하게 됩니다 일부 앱은 예약, 티켓 구매 또는 모임 예약을 지원하고 일부 앱은 이벤트를 추가하는 식으로 활용하며 일부 앱은 이벤트를 표시할 수 있죠 맞춤형 캘린더 위젯 또는 플래너를 위해서요
다른 앱들은 양방향으로 기여하죠 사람들이 이벤트를 보고 편집하여 일정을 관리하도록 돕습니다
음성 또는 영상 통화를 지원하는 앱도 가능합니다 가상 회의 확장 프로그램은 캘린더 앱의 경험을 향상할 뿐만 아니라 앱으로 돌아가는 단축어도 제공합니다
이 모든 것이 함께 시간 관리를 위한 일관된 경험을 제공합니다 나중에 몇 가지 구체적인 예를 통해 알아보기로 하고 각 영역에 대한 사항부터 시작하죠
캘린더와 통합하는 데 사용할 수 있는 프레임워크는 두 가지입니다 EventKit 프레임워크는 캘린더 데이터로 직접 작업하는 데 사용됩니다 EventKitUI는 iOS 및 Mac Catalyst 프레임워크로서 앱에 캘린더 UI를 표시하기 위한 뷰 컨트롤러를 제공합니다 각각을 자세히 살펴보죠
EventKit의 기본 유형 몇 가지부터 시작하겠습니다
EKEventStore는 캘린더 데이터의 주요 연락 창구입니다 이벤트 저장소를 사용하여 접근을 요청하고 가져오거나 저장합니다 응용 프로그램에는 이 중 하나만 있어야 합니다 EKEvent 클래스는 특정 이벤트를 나타내며 이 클래스에는 제목, 시작일 종료일, 위치와 같은 프로퍼티가 있습니다 각 이벤트는 캘린더에 속하며 이 캘린더는 EKCalendar 클래스에 의해 표시되죠 캘린더에는 제목과 색상이 있어서 이벤트에 색깔을 입히는 데 유용합니다 마지막으로, 각 캘린더 계정은 EKSource로 표시되는데 이것은 캘린더의 모음입니다 EKSource는 Ui에서 캘린더를 그룹화하는 데 유용합니다
EventKit는 기본 프레임워크로서 캘린더 데이터와 상호 작용 하기 위한 것이죠 EventKitUI는 EventKit 위에 빌드되어 몇 가지 유용한 기본 보기를 제공합니다 EventKitUI가 제공하는 세 가지 뷰 컨트롤러가 있는데요 EKEventEditViewController는 이벤트 에디터를 보여줍니다 이를 사용하여 새 이벤트를 추가하고 기존 이벤트를 변경합니다 EKEventViewController는 이벤트 세부 정보를 표시합니다 이를 사용하여 앱에 기존 이벤트 정보를 표시하죠 그리고 EKCalendarChooser는 캘린더 목록을 표시하고 단일 선택 또는 다중 선택을 지원하며 이를 사용하여 사람들이 캘린더를 선택하여 이벤트를 추가하거나 앱에 표시할 캘린더를 선택할 수 있습니다
캘린더는 비공개이므로 시스템은 앱이 권한 없이 캘린더의 이벤트를 읽거나 쓰지 못하도록 방지하죠 캘린더에 대한 앱의 접근 권한은 세 가지 수준이 있죠 접근 권한 없음 쓰기 전용 접근 권한 전체 접근 권한입니다 캘린더 접근 권한이 없는 앱은 EventKitUI 또는 Siri 이벤트 제안을 사용하여 접근할 수 있습니다 쓰기 전용 접근 권한이 있는 앱은 EventKit를 써서 직접 이벤트를 추가할 수 있으며 전체 접근 권한이 있는 앱은 기존 이벤트를 가져오거나 바꿀 수 있습니다 기존 캘린더에 접근하고 새 캘린더를 생성할 수도 있죠
캘린더와 통합하는 가장 일반적인 방법에는 새 이벤트 추가하기가 있죠 이벤트를 캘린더에 추가하는 방법은 몇 가지 더 있습니다 EventKitUI나 Siri 이벤트 제안을 사용하면 한 번에 하나씩 추가되죠 이벤트를 직접 저장하려면 EventKit를 쓰세요 이벤트를 추가하는 가장 간단한 방법은 EventKitUI가 대부분의 작업을 수행하게 하는 거죠 EKEventEditViewController로 세부 사항이 기록된 이벤트 에디터를 보여줍니다 이것으로 사람들은 캘린더를 선택하거나 다른 변경을 할 수 있죠 이벤트를 저장할지 결정하기 전에요 iOS 17에서 이 UI는 별도의 프로세스에서 실행되므로 캘린더 접근 권한을 요청할 필요가 없습니다
EventKitUI로 이벤트 추가하기 프로세스는 네 단계로 돼 있습니다 먼저 이벤트 저장소를 만듭니다 다음으로 이벤트를 만들고 세부 정보를 입력합니다 이벤트를 편집하도록 구성된 뷰 컨트롤러를 만들고 마지막으로 뷰 컨트롤러를 표시합니다 몇 가지 코드를 보면서 좀 더 자세히 알아보죠 먼저 eventStore를 만듭니다 다음으로 이벤트를 만들고 세부 정보를 입력합니다 여기서 설정한 세부 정보는 에디터 UI에서 사용되며 에디터가 표시되면 사람들이 변경할 수 있지만 추가 버튼을 탭해서 확인할 수 있으므로 올바른 세부 정보를 입력해 두면 시간을 절약할 수 있습니다 모든 이벤트에는 제목이 필요합니다 제목은 위젯과 알림 등 여러 곳에서 사용되므로 단순한 것으로 하세요
가장 중요한 프로퍼티는 시작일과 종료일입니다 DateComponents를 사용하여 시작일을 만들고
시작일을 정하면 기간을 추가하여 종료일을 계산하세요 날짜 계산을 위해 Foundation 캘린더 및 DateComponents 유형을 사용하세요 그렇지 않으면 일광 절약 시간에서 놀라운 결과가 나올 겁니다 여기 샘플 코드에서는 시작일에 두 시간을 추가합니다
이벤트가 특정 시간대에 발생하는 경우 해당 시간대도 설정해야 합니다 기본 시간대는 현재 시스템 시간대입니다
사람들이 이벤트가 열리는 위치를 알 수 있도록 위치를 설정합니다 전체 주소를 포함하거나 MapKit 핸들을 사용하면 지도 제안 및 떠날 시간 알림과 같은 기능이 활성화됩니다 마지막으로 몇 가지 메모를 더해 추가 세부 정보를 제공합니다
이벤트 프로퍼티를 설정했으면 다음 단계는 EKEventEditView Controller를 만들고 이벤트 및 이벤트 저장소 프로퍼티를 할당하는 것입니다 에디터에서 사람들은 이벤트 추가 및 취소를 할 수 있죠 사용자가 이벤트를 추가했는지 알고 싶다면 대리자 프로퍼티를 사용하고 EKEventEditViewDelegate 프로토콜을 구현합니다
마지막으로 에디터를 표시합니다 이 시점에는 이벤트가 아직 캘린더에 표시되지 않습니다 추가 버튼을 탭하면 이벤트가 저장되고 취소를 탭하면 아무것도 저장하지 않고 종료됩니다 EventKitUI로 이벤트를 추가하는 보다 완전한 예제를 보려면 'DropInLessons' 타깃을 확인하세요 'EventKit 및 EventKitUI로 캘린더 접근하기' 샘플 코드에 있습니다 캘린더에 이벤트를 추가하는 또 다른 방법은 Siri 이벤트 제안을 사용하는 것입니다 앱에서 예약한 일정에 대해서요 Siri 이벤트 제안 API는 Intent 프레임워크의 일부이며 캘린더 접근을 요청할 필요가 없고 앱에 UI를 표시하지 않습니다 대신 이러한 이벤트는 캘린더 인박스에 초대처럼 나타나죠 그런 다음 캘린더에 추가하거나 무시할 수 있습니다
Siri 이벤트 제안은 음식점이나 호텔 예약 항공편이나 렌터카와 같은 여행 예약 콘서트나 스포츠 이벤트와 같은 티켓 이벤트를 지원합니다 나중에 예약이 취소되거나 수정되면 이벤트를 업데이트할 수 있죠
Siri 이벤트 제안 API를 사용하는 프로세스 역시 네 단계로 돼 있죠 먼저 INReservation을 생성합니다 그런 다음 예약을 인텐트 및 응답으로 마무리합니다 이어서 INInteraction을 생성하고 마지막으로 시스템에 상호 작용을 제공합니다 샘플 코드를 살펴보겠습니다 예약에는 시스템이 식별하는 데 사용할 고유한 참조가 필요합니다 INSpeakableString의 인스턴스를 만들어 해당 참조를 생성합니다 vocabularyIdentifier와 spokenPhrase를 써서요 spokenPhrase는 Siri와 대화할 때 이 예약을 참조하는 데 사용할 수 있습니다
INDateComponentsRange를 사용하여 예약의 시작 및 종료 시각을 설정하고
CLPlacemark 유형을 사용하여 이벤트에 위치를 지정한 다음
이 모든 것을 통합하기 위해 INReservation의 하위 클래스 중 하나의 인스턴스를 생성합니다 음식점 예약의 경우 INRestaurantReservation을 사용하세요 이 이니셜라이저에는 표시되지 않은 몇 가지 선택적 인수가 더 있으며 각 하위 클래스에는 고유한 옵션이 있습니다 자세한 내용은 문서에서 확인하세요
다음 단계는 예약 참조로 INGetReservation DetailsIntent를 생성한 다음 INGetReservationDetailsIntent Response를 생성하는 것입니다 예약 객체를 써서요
다음으로 인텐트 및 응답을 써서 INInteraction을 생성하고
마지막으로 상호 작용의 기부 메서드를 호출합니다
이 예제는 Siri 이벤트 제안으로 할 수 있는 것의 일부에 불과합니다 Siri 이벤트 제안 생성에 대한 자세한 내용은 WWDC20의 'Siri 이벤트 제안으로 도달 범위 넓히기' 영상을 확인하세요 EventKitUI나 Siri 이벤트 제안은 이벤트를 추가하는 제일 좋은 방법이죠 쓰기 전용 접근 권한은 다음과 같은 때만 사용합니다 앱에 맞춤형 편집 UI를 표시하거나 여러 이벤트를 동시에 추가하거나 사용자 상호 작용 없이 캘린더에 이벤트를 추가해야 하는 경우죠
쓰기 전용 접근 권한을 요청하려면 NSCalendarsWriteOnlyAccess UsageDescription 키를 Info.plist에 포함해 앱에 접근 권한이 필요한 이유를 설명합니다 이 문자열은 요청 프롬프트에 표시됩니다 다음은 샘플 응용 프로그램에 대한 프롬프트입니다 '반복되는 강의를 선택한 캘린더에 저장'
쓰기 전용 접근 권한에는 몇 가지 제한 사항도 있습니다 우선, 사람들이 접근을 허용하지 않게 선택할 수 있죠 접근 권한이 있어도 앱은 캘린더의 기존 이벤트를 읽을 수 없죠 같은 앱에 추가된 이벤트를 포함해서요 또한 앱은 캘린더 목록을 읽거나 새 캘린더를 만들 수도 없습니다 쓰기 전용 접근 권한은 iOS 17 및 macOS Sonoma의 새로운 기능이죠 이것이 기존 앱에 어떤 영향을 미치는지 자세히 알아보려면 '개인정보 보호의 새 기능' 영상을 확인하세요
쓰기 전용 접근 권한으로 새 이벤트를 추가하는 것은 EventKitUI로 새 이벤트를 추가하는 것과 유사합니다 시작은 같습니다 이벤트 저장소를 생성하죠 그런 다음 쓰기 전용 접근 권한을 요청하고 접근 권한이 부여되면 새 이벤트를 생성하고 세부 정보를 입력한 다음 마지막으로 이벤트를 저장합니다 더 자세히 알아보죠 먼저 이벤트 저장소를 만듭니다 그런 다음 쓰기 전용 접근 권한을 요청합니다 requestWriteOnlyAccessToEvents 메서드를 호출해서요 반환값은 접근 권한이 부여되었는지를 나타냅니다 사람들이 접근을 거부할 수 있으니 신중하게 처리해야 합니다 접근 요청이 승인될 가능성이 가장 높을 때는 사람들이 앱에 접근 권한이 필요한 이유를 이해할 때이니 먼저 누군가가 필요 기능과 상호 작용 했을 때 요청해야 합니다 다음으로 이벤트를 생성하고 세부 정보를 입력합니다 여기에 또 다른 중요한 차이점이 있습니다 EventKitUI를 사용할 때는 입력한 세부 정보가 에디터에 표시되고 입력하지 않은 항목은 기본값이 적용됩니다 EventKit를 사용하여 이벤트를 직접 저장할 때는 아무것도 입력되지 않고 사용자가 설정한 내용이 저장됩니다 몇 가지 프로퍼티는 입력하지 않으면 저장되지 않습니다
필수 프로퍼티 중 하나는 calendar입니다 이벤트 저장소의 defaultCalendar ForNewEvents 프로퍼티를 써서 설정의 기본 설정 달력을 사용합니다
다른 필수 프로퍼티는 제목, 시작일 및 종료일이며 다른 모든 항목은 선택 사항이지만 가능한 한 많이 입력하는 것이 좋습니다
세부 정보가 입력되면 이벤트 저장소의 저장 메서드를 사용하여 이벤트를 저장합니다
EventKit로 이벤트를 추가하는 전체 예제를 보려면 'RepeatingLessons' 타깃을 확인하세요 'EventKit 및 EventKitUI로 캘린더 접근하기' 샘플 프로젝트에 있습니다
캘린더에 이벤트를 추가하려는 앱은 EventKitUI이나 Siri 이벤트 제안 혹은 쓰기 전용 접근 권한을 써야죠 캘린더 데이터를 읽어야 하는 극소수 앱을 위해 전체 접근 권한이 있습니다
전체 접근 권한은 다음 경우에만 요청하세요 앱에 기존 이벤트를 표시하거나 업데이트 또는 제거해야 하는 핵심 기능이 있을 때만요 전체 접근 권한을 요청하려면 Info.plist에 NSCalendars FullAccessUsageDescription 키를 포함하세요 이 문자열이 요청 프롬프트에 보일 겁니다 캘린더에는 중요한 정보가 포함되어 있으며 전체 접근 권한 요청 프롬프트는 포함되는 데이터의 양을 설명합니다 앱이 캘린더를 읽게 하려면 사용자의 깊은 신뢰가 필요하겠죠 사용자가 앱을 신뢰하지 않으면 요청이 거부될 수 있습니다 앱의 핵심 경험에 필수적인 경우에만 전체 접근 권한을 요청하고 전체 접근 권한이 필요한 이유가 명확할 때만 요청하세요
핵심 기능에 대한 전체 접근 권한이 필요한 경우 이벤트를 가져와야 할 수 있습니다 이렇게 하려면 먼저 이벤트 저장소를 만들고 다음으로 전체 접근 권한을 요청한 다음 술부를 만들고 마지막으로 이벤트 저장소에서 이벤트를 가져와야 합니다 이에 대한 코드를 확인해 보죠 다른 예제와 마찬가지로 이벤트 저장소부터 만들고 앱에는 이벤트 저장소가 하나만 있어야 하므로 이 저장소를 재사용해야 합니다 다음으로 전체 접근 권한을 요청합니다 requestFullAccessToEvents 메서드를 호출해서요 프롬프트가 표시되고 접근 허용 여부를 반환합니다 전체 접근 권한 프롬프트는 더 자주 거부되므로 반드시 처리해야 합니다 전체 접근 권한이 부여되면 술부를 생성합니다 이벤트 저장소의 predicate ForEvents 메서드를 호출해서요 이 술부는 날짜 범위와 선택적 캘린더 목록을 써서 가져올 이벤트를 설명합니다 이 코드는 현재 달의 범위를 사용하는데 최상의 성능을 위해 최대한 가장 짧은 범위를 사용하고 캘린더 인수를 nil로 남겨두면 결과에 모든 캘린더의 이벤트가 포함됩니다 마지막으로 이벤트를 가져옵니다 술부를 이벤트 저장소의 events(matching:) 메서드에 보내서요 이 메서드는 매칭되는 이벤트의 어레이를 반환합니다 이 어레이의 이벤트는 반드시 정렬되진 않으므로 필요하다면 결과를 정렬하세요 이벤트 가져오기의 전체 예제를 살펴보려면 'MonthlyEvents' 타깃을 확인하세요 'EventKit 및 EventKitUI로 캘린더 접근하기' 샘플 프로젝트에 있습니다
iOS 17 및 macOS Sonoma 이전 버전을 지원하려면 런타임 가용성 검사를 수행하고 iOS 17 및 macOS Sonoma 이상에서는 새로운 requestAccess 메서드를 호출하세요 이전 OS에서는 레거시 requestAccess 메서드를 호출하세요
iOS 17 또는 macOS Sonoma 이전 버전에서는 추가 사용 문자열이 필요하며 캘린더 접근 요청 시엔 NSCalendars UsageDescription 키를 포함하세요 EventKitUI를 사용하는 앱도 NSContactsUsageDescription 키를 포함해야 합니다 EventKitUI가 앱에 대한 연락처 접근을 요청할 테니까요
앱이 접근을 요청할 때 이러한 문자열이 누락되면 앱은 강제 종료 됩니다
지금까지 이벤트를 추가하는 몇 가지 방법과 이벤트를 가져오는 방법을 살펴봤습니다만 이벤트 작업만이 캘린더와 통합하는 유일한 방법은 아닙니다 앱이 음성 또는 영상 통화를 지원하는 경우 가상 회의 확장 프로그램을 사용하여 사람들이 통화를 이벤트에 직접 추가할 수 있도록 합니다 이 확장 프로그램은 두 가지 방법으로 사용됩니다 이벤트에 위치를 추가하면 위치 피커에 맞춤형 가상 회의 옵션이 나타납니다 이 예제의 옵션은 FaceTime과 Skype 가상 회의 확장 프로그램이 제공한 것입니다 이 중 하나를 탭하면 가상 회의가 이벤트에 추가되죠 가상 회의가 있는 이벤트에는 맞춤형 참가 옵션이 표시됩니다 이벤트 세부 정보에요 가상 회의 확장 프로그램을 만들려면 몇 단계만 거치면 됩니다 먼저, Xcode에서 새 가상 회의 확장 타깃을 생성합니다 다음으로 확장 프로토콜에 구현할 두 가지 메서드가 있습니다 fetchAvailableRoomTypes를 구현하여 사용 가능한 회의실 유형을 제공하고 fetchVirtualConference를 구현하여 선택한 회의실 유형에 대한 가상 회의 객체를 제공합니다 예제를 살펴보죠
먼저 Xcode에서 가상 회의 확장 타깃을 생성하는데요 새 타깃에는 EKVirtualConferenceProvider의 스텁 하위 클래스가 있습니다 재정의할 첫 번째 메서드는 fetchAvailableRoomTypes이고 회의실 유형은 위치 피커에 표시되며
각 회의실 유형에 대한 제목을 선택합니다 이는 앱 아이콘 옆의 UI에 표시됩니다
또한 각 회의실 유형에 대한 고유 식별자를 선택합니다 이 식별자는 확장 프로그램에 선택된 회의실 유형을 알리는 데 사용되죠
EKVirtualConferenceRoomType Descriptor의 인스턴스를 만듭니다 제목과 식별자를 사용해서요 앱에서 여러 회의실 유형을 지원하는 경우 각 유형에 대한 인스턴스를 만듭니다 마지막으로 회의실 유형의 어레이를 반환합니다
다음으로 구현할 메서드는 fetchVirtualConference입니다 회의실 유형 중 하나가 선택되면 호출되며 식별자 인수는 어떤 회의실이 선택되었는지 알려줍니다
가상 회의에는 하나 이상의 URL 서술자가 있으며 이 서술자는 캘린더에 참여 방법을 알려줍니다 EKVirtualConference URLDescriptor를 생성합니다 열어 볼 URL과 선택 사항인 제목을 넣어서요
URL에 유니버설 링크를 사용하여 앱을 바로 열 수 있도록 합니다 제목은 여러 참여 옵션을 구분하는 데 도움이 되며 여기서는 참여 방법이 하나뿐이므로 필요하지 않습니다
세부 정보 문자열에 추가 정보를 입력합니다 이 텍스트는 이벤트 세부 정보 Ui의 특별 가상 회의 섹션에 포함됩니다
마지막으로 이 모든 것을 종합하여 EKVirtualConferenceDescriptor를 생성하고 반환합니다 제목은 여러 회의실 유형을 구분하는 데 도움이 됩니다 이 예제에는 회의실 유형이 하나만 있으므로 제목은 nil로 둡니다
이 두 가지 방법만으로 캘린더 앱의 위치 피커에 가상 회의 옵션이 표시됩니다
이제 캘린더와 통합하는 몇 가지 방법을 살펴봤으니 앱이 기여할 수 있는 방법을 생각해 보세요 EventKitUI 또는 Siri 이벤트 제안을 사용하여 접근 요청 없이 이벤트를 추가할 수 있습니다 접근을 요청해야 하는 경우 최소한의 접근만 요청하고 필요한 경우에만 요청하세요 음성 또는 영상 통화 앱이 있는 경우 가상 회의 확장 프로그램을 구현하세요 여러분의 앱이 캘린더와 어떻게 통합되는지 보고 싶네요 시청해 주셔서 감사합니다 ♪ ♪
-
-
5:49 - Adding an event with EventKitUI
// Create an event store let store = EKEventStore() // Create an event let event = EKEvent(eventStore: store) event.title = "WWDC23 Keynote" let startDateComponents = DateComponents(year: 2023, month: 6, day: 5, hour: 10) let startDate = Calendar.current.date(from: startDateComponents)! event.startDate = startDate event.endDate = Calendar.current.date(byAdding: .hour, value: 2, to: startDate)! event.timeZone = TimeZone(identifier: "America/Los_Angeles") event.location = "1 Apple Park Way, Cupertino, CA, United States" event.notes = "Kick off an exhilarating week of technology and community." // Create a view controller let eventEditViewController = EKEventEditViewController() eventEditViewController.event = event eventEditViewController.eventStore = store eventEditViewController.editViewDelegate = self // Present the view controller present(eventEditViewController, animated: true)
-
9:17 - Siri Event Suggestions
// Create an INReservation let spokenPhrase = “Lunch at Caffè Macs” let reservationReference = INSpeakableString(vocabularyIdentifier: "df9bc3f5", spokenPhrase: spokenPhrase, pronunciationHint: nil) let duration = INDateComponentsRange(start: myEventStart, end: myEventEnd) let location = CLPlacemark(location: myCLLocation, name: "Caffè Macs", postalAddress: myAddress) let reservation = INRestaurantReservation(itemReference: reservationReference, reservationStatus: .confirmed, reservationHolderName: "Jane Appleseed", reservationDuration: duration, restaurantLocation: location) // Create an intent and response let intent = INGetReservationDetailsIntent(reservationContainerReference: reservationReference) let intentResponse = INGetReservationDetailsIntentResponse(code: .success, userActivity: nil) intentResponse.reservations = [reservation] // Create an INInteraction let interaction = INInteraction(intent: intent, response: intentResponse) // Donate the interaction to the system interaction.donate()
-
12:41 - Adding an event with write-only access
// Create an event store let store = EKEventStore() // Request write-only access guard try await store.requestWriteOnlyAccessToEvents() else { return } // Create an event let event = EKEvent(eventStore: store) event.calendar = store.defaultCalendarForNewEvents event.title = "WWDC23 Keynote" event.startDate = myEventStartDate event.endDate = myEventEndDate event.timeZone = TimeZone(identifier: "America/Los_Angeles") event.location = "1 Apple Park Way, Cupertino, CA, United States" event.notes = "Kick off an exhilarating week of technology and community." // Save the event guard try eventStore.save(event, span: .thisEvent) else { return }
-
15:51 - Fetch events
// Create an event store let store = EKEventStore() // Request full access guard try await store.requestFullAccessToEvents() else { return } // Create a predicate guard let interval = Calendar.current.dateInterval(of: .month, for: Date()) else { return } let predicate = store.predicateForEvents(withStart: interval.start, end: interval.end, calendars: nil) // Fetch the events let events = store.events(matching: predicate) let sortedEvents = events.sorted { $0.compareStartDate(with: $1) == .orderedAscending }
-
19:18 - Virtual conference extension
// Create the extension target class VirtualConferenceProvider: EKVirtualConferenceProvider { // Provide the room types override func fetchAvailableRoomTypes() async throws -> [EKVirtualConferenceRoomTypeDescriptor] { let title = "My Room" let identifier = "my_room" let roomType = EKVirtualConferenceRoomTypeDescriptor(title: title, identifier: identifier) return [roomType] } // Provide the virtual conference override func fetchVirtualConference(identifier: EKVirtualConferenceRoomTypeIdentifier) async throws -> EKVirtualConferenceDescriptor { let urlDescriptor = EKVirtualConferenceURLDescriptor(title: nil, url: myURL) let details = "Enter the meeting code 12345 to enter the meeting." return EKVirtualConferenceDescriptor(title: nil, urlDescriptors: [urlDescriptor], conferenceDetails: details) } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.