App Schemas: 앱을 Siri에서 사용할 수 있게 만들기
WWDC 2026에서 한 Apple 엔지니어는 탭에만 반응하던 SwiftUI 캘린더 앱을, Siri가 이벤트를 검색하고, 이름과 메모 내용으로 질문에 답하며, 음성으로 생성하고 업데이트하고, 맞춤형 결과 카드를 렌더링하는 앱으로 바꿔 보였습니다. 거기에 도달하기 위해 작성한 것은 세 개의 struct와 몇 개의 코드 스니펫을 채우는 일뿐이었습니다.1 이 변화의 배경에 있는 메커니즘이 바로 App Schemas입니다. 이는 앱의 콘텐츠와 동작을 Siri가 이미 이해하는 형태로 기술하는 방법으로, 학습용 문구도 없고 개발자 쪽의 자연어 처리도 없습니다.1 이 세션은 CometCal이라는 샘플 프로젝트를 중심으로 한 코드 어롱(code-along) 형식이며, 우주를 주제로 한 외형 아래에 깔린 교훈은 구조적입니다. Siri에게 여러분의 어휘를 가르치는 것이 아닙니다. 여러분의 데이터와 동작을 Siri가 이미 알고 있는 형태에 맞춰 선언하면, 나머지는 자연스럽게 따라옵니다.
이 글에서는 그 결과를 떠받치는 세 가지 기둥을 차례로 살펴봅니다. 스키마-도메인 모델, IndexedEntity를 통한 Spotlight로의 시맨틱 기증(donation), 그리고 화면 인식과 음성 기반 업데이트를 안전하게 만들어 주는 valueState 구분입니다. 아래 내용은 모두 세션에서 직접 나온 것입니다. 이 글의 주제는 App Intents의 백그라운드 실행과는 다릅니다. 그쪽은 UI를 실행하지 않고 작업을 수행하는 것을 다루지만, 여기서의 초점은 Siri가 어떻게 콘텐츠를 추론하고 그에 따라 동작하는가입니다.
TL;DR
App Schemas는 앱의 엔티티, 동작 파라미터, 출력을 Siri가 이미 이해하는 형태로 기술하며, App Schema Domains로 정리됩니다. calendar 도메인은 이벤트, 캘린더, 참석자, 그리고 그것들에 대한 동작을 포괄하며, 학습용 문구도 개발자 쪽 NLP도 없습니다.1- 스키마화된 엔티티는 Xcode 코드 스니펫에서 나옵니다.
calendar_와 같은 도메인 접두사를 입력하고 스니펫(예:calendar_calendar)을 선택하면, 엔티티의 매크로, 프로퍼티, 표시 표현, 쿼리 스텁이 골격으로 생성됩니다.1 - 엔티티를
IndexedEntity에 준수시키고indexAppEntities를 통해CSSearchableIndex에 기증하면(그리고deleteAppEntities로 제거하면), 맞춤형 프로퍼티 쿼리 없이도 Siri가 이름, 프로퍼티, 또는 맥락으로 그것을 해석할 수 있습니다.1 - 두 개의 뷰 모디파이어, 즉 리스트에 붙이는
.appEntityIdentifier와 상세 뷰에 붙이는.userActivity(각각EntityIdentifier를 지닙니다)는 Siri에게 화면 인식을 부여합니다. 그래서 “이 이벤트의 참석자들에게 이메일을 보내” 같은 요청이 이벤트 이름을 지정하지 않고도 해석됩니다.1 - 업데이트 인텐트는
IntentParameter.valueState를 노출합니다. 값을 동반한.set, nil을 동반한.set,.unset이 각각 새로운 값, 명시적 삭제, 파라미터의 부재를 구분하므로, Siri 기반 편집이 모호해지지 않습니다.1
App Schemas란 실제로 무엇인가 (세션 344)
Swift Intelligence Frameworks 팀의 Justin이 Xcode를 열기 전에 App Schemas를 설명합니다. 3:12부터 시작합니다.
Siri는 App Intents 프레임워크를 통해 앱에 도달하고, 그 위에서의 추론은 Apple Intelligence가 담당합니다.1 CometCal에서의 출발 문제는 분명합니다. “지금으로서는 Siri가 CometCal 안에서 캘린더나 이벤트가 무엇을 의미하는지 전혀 모릅니다.”1 App Schemas가 그 간극을 메웁니다. 세션의 표현을 빌리면, 이것들은 “내 앱의 콘텐츠와 동작을 Siri가 이미 이해할 수 있는 형태로 기술합니다. 내 엔티티의 구조, 동작의 파라미터, 그리고 출력을 정의합니다. 학습용 문구도 없고, 내 쪽의 자연어 처리도 없습니다.”1
정리의 단위는 App Schema Domain입니다. calendar 도메인은 “일정 관리와 관련된 모든 것, 즉 이벤트, 캘린더, 참석자, 그리고 그것들을 다루는 동작을 포괄합니다.”1 형태가 미리 정의되어 있기 때문에 목록화는 에디터가 해 줍니다. 엔지니어는 CalendarEntity 파일을 만들고, AppIntents를 import한 다음 calendar_를 입력합니다. 그러면 “Xcode가 자동 완성에서 바로 Calendar 도메인의 모든 스키마를 제시합니다.”1 calendar_calendar를 선택하면 구조가 채워집니다. 엔티티 매크로, 프로퍼티, 표시 표현, 쿼리 스텁이 갖춰지면서, 세션이 “스키마화된 엔티티, 즉 Siri가 추론할 수 있는 타입”이라고 부르는 것이 만들어집니다.1
명명 규칙은 신중하게 짚어 둘 필요가 있습니다. 스키마 스니펫의 이름들은 에디터에서 소문자에 밑줄을 접두로 붙인 식별자(calendar_calendar, calendar_attendee, calendar_event, calendar_createEvent, calendar_updateEvent, 그리고 calendar_attendeeStatus, calendar_attendeeType 같은 enum 스니펫)로 나타나며, 음성 전사도 그렇게 표기합니다. 그것들이 골격으로 생성하는 Swift 타입(@AppEntity 매크로, DisplayRepresentation, 쿼리 프로토콜 준수)은 일반적인 Swift 대소문자 규칙을 따릅니다. 빌드에 사용하기 전에 각 심볼의 정확한 철자와 대소문자를 Apple의 App Intents 문서와 다운로드 가능한 CometCal 샘플 프로젝트에서 확인하세요. 음성으로 진행하는 코드 어롱은 대소문자에 대한 정확한 참고 자료가 되지 못하기 때문입니다.
스키마 모델의 보상은 아주 적은 코드로 얻는 도달 범위입니다. 세션은 콘텐츠 계층 전체를 “세 개의 struct와 몇 개의 코드 스니펫을 채우는 것”으로 표현합니다.1 CometCal은 풍부함이 점점 더해지는 세 개의 엔티티를 구축합니다. 캘린더, 참석자, 그리고 앞의 둘을 하나로 엮는 이벤트입니다. 이벤트는 “앞서 구축한 다른 엔티티들과 조합됩니다.” 그 캘린더는 CalendarEntity이고, 참석자는 AttendeeEntity의 배열이며, “Siri는 App Schemas를 통해 이러한 관계를 이해합니다.”1 스키마는 또한 무엇이 필수이고 무엇이 선택인지도 결정합니다. 제목이나 시작 일시 같은 필수 항목은 직접 연결되고, 앱이 사용하지 않는 선택 스키마 프로퍼티(세션은 이동 시간과 가상 위치를 듭니다)는 설정되지 않은 채로 둘 수 있으며, 데이터 모델에는 있지만 스키마에는 없는 프로퍼티, 예를 들어 isFavorite 같은 것도 엔티티에 추가할 수 있습니다.1
이벤트에는 두 가지 스키마 메커니즘이 더 나타납니다. Union 값을 쓰면 하나의 프로퍼티가 여러 타입 중 하나를 담을 수 있습니다. 위치는 “GeoToolbox 프레임워크의 PlaceDescriptor이거나 String 중 하나”일 수 있고, 알람은 Duration이거나 Date 중 하나일 수 있습니다.1 반복 프로퍼티는 Foundation의 Calendar.RecurrenceRule을 사용하며, 매일·매주·매월·매년 경우에 대해 CometCal 자체의 빈도 enum과 상호 변환합니다.1 스키마화된 enum(세션은 EventEntityStatus라고 부르는 이벤트 상태 enum과 위의 참석자 enum들을 가리킵니다)은 스니펫에서 완전한 형태로 도착하고, 앱은 해당하는 경우들을 채택합니다. 만약 앱이 다른 용어를 쓴다면, 기존 모델을 스키마의 경우들에 매핑하여 “Siri가 그 형태를 인식할 수 있게” 합니다.1
IndexedEntity를 통한 시맨틱 기증
스키마는 Siri에게 어휘를 줍니다. 기증은 추론할 실제 데이터를 Siri에게 줍니다. 이 둘은 별개의 단계이며, 세션은 두 번째 단계를 놓치기 쉽다고 분명히 말합니다. “IndexedEntity는 내가 인덱싱하는 콘텐츠의 형태를 정의하지만, 엔티티는 여전히 기증되어야 합니다.”1
엔티티를 IndexedEntity 프로토콜에 준수시키는 것이 텍스트만이 아니라 의미에 의한 매칭을 가능하게 합니다.1 그 이유는 검색 인덱스에 있습니다. 준수는 “내 앱이 Spotlight 인덱스를 사용해 엔티티를 기증하여 시맨틱 이해의 이점을 얻을 수 있게” 하고, 일단 엔티티가 기증되면 “Siri는 맞춤형 프로퍼티 쿼리를 요구하지 않고도 이름, 프로퍼티, 또는 맥락으로 그것을 해석할 수 있습니다.”1 그 마지막 구절이 핵심 전부입니다. “승무원 점심”이나 “산소를 언급하는 이벤트”를 위한 별도의 매처를 작성할 필요가 없습니다. Siri는 기증된 제목과 메모 내용을 직접 검색하며, “앱의 콘텐츠를 사용해 모든 질문에 답합니다. 맞춤형 자연어 처리가 필요 없습니다… 그저 엔티티와 스키마뿐입니다.”1
기증은 CSSearchableIndex를 통해 이루어집니다. CometCal은 앱 고유의 이름 아래 CalendarManager 이니셜라이저에서 생성된 CSSearchableIndex 인스턴스를 보유합니다.1 세션이 명시하는 규칙은 “캘린더, 아니 인덱싱된 어떤 엔티티든 변경될 때마다 인덱스를 업데이트해야 한다”는 것입니다.1 그래서 데이터 계층은 쓰기 시점에 기증합니다. 생성 경로는 반환하기 전에 검색 인덱스를 전달하여 indexAppEntities를 호출하고, 업데이트 경로는 변경된 엔티티를 다시 인덱싱하며, 삭제 경로는 “엔티티의 id와 타입을 전달하여” deleteAppEntities를 호출합니다.1 캘린더 엔티티를 연결한 뒤, 엔지니어는 “Lunar Orbit Log”라는 이름의 캘린더를 만들고, 스와이프하여 검색하자 아이콘과 제목과 함께 그것을 찾아냅니다. 기증이 적용되었다는 증거입니다.1
모든 엔티티가 인덱싱되어야 하는 것은 아니며, 참석자가 그 규칙을 가르치는 반례입니다. AttendeeEntity는 IndexedEntity가 아니라 TransientAppEntity에 준수합니다. 이는 “고유 식별자가 필요 없고 쿼리 대상이 되도록 의도되지 않은 임시 엔티티”입니다.1 그 근거는 모델링의 규율에 있습니다. CometCal에서 참석자는 “사람 그 자체가 아니라, 특정 이벤트에 대한 한 사람의 참여”를 나타냅니다. 같은 사람이 여러 이벤트에 참석할 수 있으며, “각 참석을 따로 인덱싱하면 Spotlight에 중복된 결과가 생기게 됩니다.”1 참석자는 항상 그 이벤트를 통해 도달되므로 유지해야 할 독립적인 조회 경로가 없고, TransientAppEntity는 “그 점을 명시적으로 만듭니다… 작성할 쿼리도, 유지할 인덱스도 없습니다.”1 참석자는 또한 IntentPerson을 도입합니다. 이는 “이름과 연락처 정보를 가진 사람을 나타내는 시스템의 표준 방식”으로, 참석자의 이메일을 Mail에 넘겨 메시지를 작성하게 하는 데 유용합니다.1
인덱싱된 엔티티에는 여전히 쿼리 배선이 필요합니다. 쿼리는 @Dependency 프로퍼티 래퍼를 통해 데이터 계층을 보유합니다. 이는 “App Intents가 공유 리소스를 인텐트와 쿼리에 주입하는 방식”이며, 그래서 쿼리는 새 인스턴스가 아니라 등록된 단 하나의 CalendarManager를 사용하고, 매니저가 main-actor이므로 쿼리도 main-actor로 표시됩니다.1 필수 EntityQuery 메서드는 시스템이 이미 ID를 아는 경우를 위해 ID로 가져오고, allEntities 메서드를 가진 EnumerableEntityQuery에 준수시키면 이벤트를 생성하는 동안 Siri가 선택지로 제시해야 할 때 시스템이 나중에 사용 가능한 캘린더를 나열할 수 있습니다.1 DisplayRepresentation(제목과 시스템 캘린더 이미지)은 엔티티를 어떻게 렌더링할지 Siri와 Spotlight에 알려 줍니다.1
여기서 이름을 붙여 둘 만한 내비게이션의 이음매가 있습니다. 기증만으로는 사용자가 앱의 메인 화면에 도착하기 때문입니다. system.open 스키마에 준수하고, EventEntity를 대상으로 받으며, 내비게이션 계층에 그곳으로 이동하라고 지시하는 OpenEventIntent가 그 간극을 메웁니다. 시스템은 이것을 “누군가 Spotlight나 Siri에서 이벤트 결과를 탭하거나, Siri에게 이벤트를 열어 달라고 요청할 때마다” 호출하므로, 탭된 결과는 곧장 그 이벤트의 상세 뷰로 열립니다.1
화면 인식과 valueState 구분
처음 두 기둥은 Siri가 이름으로 콘텐츠를 찾게 합니다. 세 번째 기둥은 Siri가 이미 사용자 앞에 있는 것을 사용하게 하고, 그런 다음 모호함 없이 그에 따라 동작하게 합니다.
화면 인식의 비용은 “단 두 개의 뷰 모디파이어”입니다.1 리스트 뷰에서는 .appEntityIdentifier가 리스트에 붙어 “각 이벤트 엔티티에 대한 EntityIdentifier를 전달”하고, 이것이 “리스트를 그 엔티티들과 연결하여, 누군가 리스트를 둘러볼 때 시스템이 어떤 이벤트들이 화면에 있는지 알게” 합니다.1 상세 뷰에서는 .userActivity가 초점이 맞춰진 단일 이벤트의 EntityIdentifier를 지니며, “그 특정한 한 이벤트가 정중앙에 있다”는 것을 시스템에 알려 “Siri가 이 이벤트를 정확히 지금 보고 있는 것으로 해석할 수 있게” 합니다.1 둘 다 갖춰지면, 이벤트의 상세 뷰를 보고 있는 사용자는 “이 이벤트의 참석자들에게 이메일을 보내고 누군가에게 초콜릿과 마시멜로를 가져와 달라고 요청해”라고 말할 수 있고, Siri는 화면 위 이벤트에 대한 이해를 사용해 참석자들을 찾아내 Mail에 넘깁니다. 제목은 필요 없습니다.1
콘텐츠에 대해 동작하는 것은 그것을 읽는 것과 같은 패턴을 거꾸로 실행하는 일입니다. 인텐트도 스니펫에서 나옵니다. calendar_createEvent 스니펫은 매크로, 스키마, 스키마가 요구하는 파라미터, 그리고 perform 스텁과 함께 인텐트의 골격을 생성합니다.1 perform 로직은 세션이 분명하게 말하는 세 단계 형태입니다. “인텐트의 파라미터를 데이터 계층이 이해하는 것으로 해석하고, 동작을 수행하고, 그 결과를 엔티티로 반환합니다.”1 생성의 경우, 이는 union 값에서 위치를 추출하고, 반복이 제공되면 변환하고, 매니저의 생성 메서드를 호출하고, EventEntity를 반환하는 것을 의미합니다.1 인텐트가 스키마에 준수하기 때문에 “Siri가 무거운 작업을 모두 처리할 수 있습니다. 언어를 해석하고, 명확히 해 달라고 묻고, 세부 사항을 확인하는 일입니다.” 그래서 개발자는 그 대화를 결코 작성하지 않습니다.1
업데이트는 음성 기반 편집을 신뢰할 수 있게 만드는 미묘한 지점을 드러냅니다. calendar_updateEvent의 대부분 파라미터는 선택입니다. 사용자는 보통 한두 가지만 바꾸기 때문이고, “이벤트 파라미터는 Siri가 해석하는 것이고, 나머지는 모두 선택입니다.”1 단순한 nil 검사는 진짜 질문에 답할 수 없습니다. 세션의 표현을 빌리면, “recurrence가 nil일 때, 그것은 ‘바꾸지 마’를 뜻하는가, 아니면 ‘제거해’를 뜻하는가? 단순한 nil 검사는 내가 어떤 경우를 다루고 있는지 알려 주지 않습니다.”1 그 답이 IntentParameter.valueState입니다. 이는 인텐트 매크로가 각 프로퍼티를 IntentParameter로 감싸기 때문에 노출됩니다. 세 가지 상태는 각각 분명한 의미를 지닙니다. “실제 값을 동반한 .set은 새로운 값이 제공되었음을 뜻합니다. nil 값을 동반한 .set은 그것이 명시적으로 삭제되었음을 뜻합니다. .unset은 그 파라미터가 요청에 포함되지 않았음을 뜻합니다.”1 이 구분은 “값을 삭제하는 것이 의미 있는 동작이 되는 모든 선택 파라미터에 적용됩니다.” 바로 그래서 “이 이벤트를 반복하지 마”가 recurrence를 손대지 않고 두는 대신 확실하게 삭제하는 것입니다.1
두 가지 마무리 손질이 동작 계층을 완성합니다. 맞춤형 결과 카드는 Siri의 기본 표시 표현 카드를 대체합니다. perform 메서드의 반환 타입에 ShowsSnippetView를 추가하고 준비된 SwiftUI 뷰(세션의 것은 EventEntity를 받습니다)를 전달하면, Siri 안에 앱 고유의 스타일이 렌더링됩니다. 이는 “결과를 반환하는 다른 어떤 인텐트에도 통하는” 접근법입니다.1 그리고 DeleteEventIntent는 “셋 중 가장 단순한” 것으로, 이벤트와 반복 이벤트를 위한 선택적 span만 받습니다. Siri는 “무언가가 제거되기 전에 확인 대화상자를 자동으로 처리하고”, 둘 이상의 이벤트가 일치할 때 모호함을 해소합니다.1
핵심 요점
App Intents를 도입하는 iOS 개발자를 위해:
- 먼저 스키마에 손을 뻗으세요. Xcode에서
calendar_같은 도메인 접두사를 입력하고 자동 완성이 사용 가능한 스니펫을 나열하게 하세요. 스니펫이 매크로, 프로퍼티, 표시 표현, 쿼리 스텁을 골격으로 생성하므로, 구조를 고안하는 대신 타입과 매핑을 채우기만 하면 됩니다.1 - 엔티티마다 인덱스를 가질 만한지 결정하세요. 지속적이고 쿼리 가능한 콘텐츠는
IndexedEntity에 준수시켜 기증하고, 항상 부모를 통해 도달되며 인덱싱하면 Spotlight를 오염시키기만 할 참여형 레코드(CometCal의 참석자)에는TransientAppEntity를 사용하세요.1 - 빌드하기 전에 정확한 심볼 철자와 대소문자를 Apple의 App Intents 문서와 CometCal 샘플에서 확인하세요. 코드 어롱의 이름들은 음성 전사에서 나온 것이기 때문입니다.
음성과 Apple Intelligence 흐름을 설계하는 팀을 위해:
- 기증을 쓰기 경로의 책임으로 다루세요. 생성과 업데이트에서
indexAppEntities를, 삭제에서deleteAppEntities를 엔티티의 id와 타입을 키로 하여 호출하면, Siri의 인덱스가 데이터에서 결코 어긋나지 않습니다.1 - 화면 인식을 일찍 추가하세요. 리스트에
.appEntityIdentifier, 상세 뷰에.userActivity(각각EntityIdentifier를 지닙니다)를 붙이면, 사용자가 제목 대신 “이 이벤트”라고 말할 수 있습니다.1 - 업데이트 인텐트에서
valueState를 명시적으로 처리하세요. 값을 동반한.set, nil을 동반한.set,.unset으로 분기하면, 명시적 삭제가 결코 “변경하지 않음”으로 읽히지 않습니다.1
FAQ
App Intents에서 App Schemas란 무엇인가요?
App Schemas는 앱의 콘텐츠와 동작을 Siri가 이미 이해하는 형태로 기술합니다. 앱 엔티티의 구조, 동작의 파라미터, 그리고 출력을 정의하며, 학습용 문구도 개발자 쪽의 자연어 처리도 없습니다. 이것들은 App Schema Domains로 정리됩니다. calendar 도메인은 이벤트, 캘린더, 참석자, 그리고 그것들에 대한 동작을 포괄합니다. Xcode에서는 calendar_ 같은 도메인 접두사를 입력하고 calendar_calendar 같은 코드 스니펫을 선택하여 스키마를 도입하며, 이것이 엔티티를 골격으로 생성합니다.1
Siri는 어떻게 이름이나 맥락으로 내 앱의 콘텐츠를 해석하나요?
엔티티를 IndexedEntity 프로토콜에 준수시키고, 생성과 업데이트에서 indexAppEntities를, 삭제에서 엔티티의 id와 타입을 전달하여 deleteAppEntities를 호출함으로써 CSSearchableIndex(Spotlight 인덱스)에 기증하세요. 기증은 Siri에게 “시맨틱 이해”를 부여하여, 맞춤형 프로퍼티 쿼리 없이도 이름, 프로퍼티, 또는 맥락으로 엔티티를 해석하게 합니다. 여기에는 “산소를 언급하는 이벤트가 뭐야?” 같은 질문을 위해 메모 내용을 검색하는 것도 포함됩니다.1
IndexedEntity 대신 TransientAppEntity를 언제 사용해야 하나요?
고유 식별자가 필요 없고 쿼리 대상이 되도록 의도되지 않은 임시 엔티티에는 TransientAppEntity를 사용하세요. CometCal의 참석자가 여기에 맞습니다. 참석자는 사람 자체가 아니라 특정 이벤트에 대한 한 사람의 참여를 나타내기 때문입니다. 같은 사람이 여러 이벤트에 참석하고, 각 참석을 따로 인덱싱하면 Spotlight에 중복된 결과가 생기게 됩니다. 참석자는 오직 그 이벤트를 통해서만 도달되므로 독립적인 조회 경로가 없고, 따라서 이 임시 엔티티에는 쿼리도 인덱스도 필요 없습니다.1
valueState란 무엇이고, 업데이트 인텐트에 왜 중요한가요?
업데이트 인텐트에서 App Intents 매크로는 각 프로퍼티를 IntentParameter로 감싸고, 이것이 valueState를 노출합니다. 이는 nil 검사로는 구분할 수 없는 세 가지 경우를 구분합니다. 값을 동반한 .set은 새 값을 뜻하고, nil을 동반한 .set은 값이 명시적으로 삭제되었음을 뜻하며, .unset은 파라미터가 요청에 포함되지 않았음을 뜻합니다. 이 구분 덕분에 Siri 기반 편집이 프로퍼티를 삭제할 수 있고(예: “이 이벤트를 반복하지 마”), 그것이 “변경하지 않음”으로 혼동되지 않습니다.1
Siri에게 내 앱의 화면 인식을 어떻게 부여하나요?
두 개의 뷰 모디파이어를 추가하세요. 리스트 뷰에 .appEntityIdentifier를 붙이고 각 이벤트 엔티티에 대한 EntityIdentifier를 전달하면, 둘러보는 동안 시스템이 어떤 이벤트들이 화면에 있는지 압니다. 상세 뷰에 EntityIdentifier를 동반한 .userActivity를 붙이면, 시스템이 특정한 한 이벤트가 초점에 있음을 압니다. 둘이 함께 작동하면 사용자가 “이 이벤트의 참석자들에게 이메일을 보내”라고 말할 수 있고, Siri는 “이 이벤트”를 정확히 지금 보고 있는 것으로 해석합니다.1
이 글은 Apple의 intelligence frameworks에 관한 클러스터에 속합니다. App Schemas가 토대로 삼는 프레임워크에 대해서는, 먼저 App Intents: 앱으로 향하는 Apple의 새로운 API부터 시작하세요. UI를 실행하지 않고 인텐트 작업을 수행하는 것에 대해서는, 여기서 다루는 콘텐츠 추론과는 별개의 관심사이지만 App Intents의 백그라운드 실행을 읽어 보세요. 시맨틱 해석 뒤에 있는 더 넓은 Spotlight 기증 이야기에 대해서는 온디바이스 AI와 Spotlight 미디어 인덱싱을 보세요. 시리즈 전체의 허브는 Apple Ecosystem 시리즈입니다.
참고 문헌
-
Apple, WWDC 2026 session 344, Code-along: Make your app available to Siri. 출처: App Schemas와 App Schema Domains(calendar 도메인; 학습용 문구 없음, NLP 없음); Xcode 스니펫을 통한 스키마화된 엔티티(
calendar_calendar,calendar_attendee,calendar_event,calendar_createEvent,calendar_updateEvent,calendar_attendeeStatus,calendar_attendeeType);IndexedEntity와indexAppEntities/deleteAppEntities를 통한CSSearchableIndex로의 Spotlight 기증; 이름, 프로퍼티, 또는 맥락에 의한 해석;TransientAppEntity와 참석자 모델링 근거;IntentPerson; union 값(GeoToolbox의PlaceDescriptor, String;Duration또는Date알람)과Calendar.RecurrenceRule;@Dependency래퍼,EntityQuery,EnumerableEntityQuery,DisplayRepresentation;system.open의OpenEventIntent;.appEntityIdentifier와EntityIdentifier를 지닌.userActivity를 통한 화면 인식;IntentParameter.valueState(.set/.unset);ShowsSnippetView맞춤형 결과 카드;DeleteEventIntent의 확인과 모호함 해소; 그리고 자동화된 테스트를 위해 언급된AppIntentsTesting프레임워크. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩