View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

    • 개요
    • 알아보기
    • Apple Developer Program

    알림 받기

    • 최신 뉴스
    • Hello Developer
    • 플랫폼

    플랫폼 탐색

    • Apple 플랫폼
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    피처링

    • 디자인
    • 배포
    • 게임
    • 액세서리
    • 웹
    • 홈
    • CarPlay
    • 기술

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 머신 러닝 및 AI
    • 보안
    • Xcode Cloud
    • 커뮤니티

    커뮤니티 탐색

    • 개요
    • Apple과의 만남 이벤트
    • 커뮤니티 주도 이벤트
    • 개발자 포럼
    • 오픈 소스

    피처링

    • WWDC
    • Swift Student Challenge
    • 개발자 이야기
    • App Store 어워드
    • Apple 디자인 어워드
    • 문서

    문서 탐색

    • 문서 라이브러리
    • 기술 개요
    • 샘플 코드
    • 휴먼 인터페이스 가이드라인
    • 비디오

    릴리즈 노트

    • 피처링 업데이트
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • 다운로드

    다운로드 탐색

    • 모든 다운로드
    • 운영 체제
    • 애플리케이션
    • 디자인 리소스

    피처링

    • Xcode
    • TestFlight
    • 서체
    • SF Symbols
    • Icon Composer
    • 지원

    지원 탐색

    • 개요
    • 도움말
    • 개발자 포럼
    • 피드백 지원
    • 문의하기

    피처링

    • 계정 도움말
    • 앱 심사 지침
    • App Store Connect 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

    • 이벤트
    • 뉴스
    • 포럼
    • 샘플 코드
    • 비디오
 

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 코드
  • 앱에 시각 지능을 통합하기 위한 모범 사례

    시각 지능으로 어떻게 앱 내 콘텐츠 탐색을 혁신할 수 있는지 인사이트를 얻어 보세요. 엔티티를 정의하고, 이미지를 처리하며, 다양한 결과 유형을 효과적으로 처리하는 방법을 살펴보세요. 속도와 관련성을 최적화하는 모범 사례를 알아보고, 인텐트가 탭 한 번으로 콘텐츠 열기 또는 재생하기 같은 직접적인 동작을 어떻게 구현하는지 살펴보세요.

    챕터

    • 0:07 - Introduction
    • 2:02 - Defining your content
    • 5:03 - Implementing a query
    • 8:18 - Opening results
    • 10:03 - Mac and iPad adoption
    • 12:27 - Returning multiple result types
    • 12:56 - Continuing search in your app
    • 14:27 - System store integrations
    • 17:16 - Next steps

    리소스

    • Integrating your app with visual intelligence
    • Visual Intelligence
      • HD 비디오
      • SD 비디오
  • 비디오 검색…
    • 3:21 - Define the content you want to return as an App Entity

      // Define the content you want to return as an App Entity
        import AppIntents
        
        struct AlbumEntity: AppEntity {
            var id: String
            @Property var name: String
            @Property var artistName: String
            var coverArtData: Data
            
            var displayRepresentation: DisplayRepresentation {
                DisplayRepresentation( 
                    title: "\(name)",
                    subtitle: "\(artistName)",
                    image: .init(data: coverArtData)
                )   
            }   
            
            static let defaultQuery = AlbumEntityQuery()
            
            static var typeDisplayRepresentation: TypeDisplayRepresentation { "Album" }
        }   
        
        struct AlbumEntityQuery: EntityQuery {
            @Dependency var catalog: AlbumCatalog
            func entities(for identifiers: [String]) async throws -> [AlbumEntity] {
                catalog.albums(for: identifiers)
            }
        }
    • 5:39 - Adopt IntentValueQuery to return results

      // Adopt IntentValueQuery to return visual search results
        import AppIntents
        import VisualIntelligence
        
        struct SearchHandler: IntentValueQuery {
            @Dependency var catalog: AlbumCatalog
            @Dependency var concertFinder: ConcertFinder
            
            func values(for input: SemanticContentDescriptor) async throws -> [VisualSearchResult] {
                guard let pixelBuffer = input.pixelBuffer else {
                    return []
                }   
                
                let albums = try await catalog.search(matching: pixelBuffer)
                
                return albums.map { VisualSearchResult.album($0) }
            }
        }
      
        --- snippet.
    • 6:24 - Build a catalog of albums with precomputed feature prints

      // Build a catalog of albums with precomputed feature prints
        import Vision
        
        @Observable
        class AlbumCatalog {
            static let shared = AlbumCatalog()
            
            struct CatalogEntry: Sendable {
                let album: AlbumEntity
                let featurePrint: FeaturePrintObservation
            }   
            
            private(set) var entries: [CatalogEntry] = []
            
            private func generateFeaturePrint(
                for image: CGImage
            ) async throws -> FeaturePrintObservation {
                let request = GenerateImageFeaturePrintRequest()
                let result = try await request.perform(on: image)
                return result
            }
        }
    • 6:45 - Search the catalog for albums matching the captured image

      // Search the catalog for albums matching the captured image
        func search(matching pixelBuffer: CVReadOnlyPixelBuffer, limit: Int = 10, maxDistance: Double = 1.0) async throws ->
        [AlbumEntity] {
            var cgImage: CGImage?
            _ = pixelBuffer.withUnsafeBuffer { VTCreateCGImageFromCVPixelBuffer($0, options: nil, imageOut: &cgImage) }
            guard let cgImage else { return [] }
            
            let queryPrint = try await generateFeaturePrint(for: cgImage)
            
            return try entries.compactMap { entry -> (album: AlbumEntity, distance: Double)? in
                let distance = try queryPrint.distance(to: entry.featurePrint)
                guard distance <= maxDistance else { return nil }
                return (entry.album, distance)
            }   
            .sorted { $0.distance < $1.distance }
            .prefix(limit)
            .map { $0.album }
        }   
        
        --
    • 8:27 - Create an open intent to land users on the right screen

      // Create an open intent to land users on the right screen
        import AppIntents
        
        struct OpenAlbumIntent: OpenIntent {
            static let title: LocalizedStringResource = "Open Album"
            
            @Parameter(title: "Album")
            var target: AlbumEntity
            
            @Dependency var appState: AppState
            
            func perform() async throws -> some IntentResult {
                await appState.openAlbum(id: target.id)
                return .result()
            }
        }
    • 12:05 - Use UnionValue to return multiple visual search result types

      // Use UnionValue to return multiple visual search result types
        @UnionValue
        enum VisualSearchResult {
            case album(AlbumEntity)
            case concert(ConcertEntity)
        }   
        
        struct OpenConcertIntent: OpenIntent {
            static let title: LocalizedStringResource = "Open Concert"
            
            @Parameter(title: "Concert")
            var target: ConcertEntity
            
            @Dependency var appState: AppState
            
            func perform() async throws -> some IntentResult {
                await appState.openConcert(id: target.id)
                return .result()
            }
        }
    • 12:18 - Expand the IntentValueQuery to return the UnionValue

      // Expand the IntentValueQuery to return the UnionValue
        struct SearchHandler: IntentValueQuery {
            @Dependency var catalog: AlbumCatalog
            @Dependency var concertFinder: ConcertFinder
            
            func values(for input: SemanticContentDescriptor) async throws -> [VisualSearchResult] {
                guard let pixelBuffer = input.pixelBuffer else {
                    return []
                }   
                
                let albums = try await catalog.search(matching: pixelBuffer)
                
                let artists = albums.map { $0.artistName }
                
                let concerts = await concertFinder.findNearby(byArtists: artists)
      
                return albums.map { VisualSearchResult.album($0) }
                    + concerts.map { VisualSearchResult.concert($0) }
            }
        }
    • 13:13 - Provide a link to in-app search

      // Provide a link to in-app search
        @AppIntent(schema: .visualIntelligence.semanticContentSearch)
        struct SemanticContentSearchIntent: AppIntent {
            static let title: LocalizedStringResource = "Search in app"
            static let openAppWhenRun: Bool = true
            
            var semanticContent: SemanticContentDescriptor
            @Dependency var catalog: AlbumCatalog
            @Dependency var concertFinder: ConcertFinder
            @Dependency var appState: AppState
            
            func perform() async throws -> some IntentResult {
                guard let pixelBuffer = semanticContent.pixelBuffer else { return .result() }
                let albums = try await catalog.search(matching: pixelBuffer)
                let artists = albums.map { $0.artistName }
                let concerts = await concertFinder.findNearby(byArtists: artists)
                await appState.openSearch(albums: albums, concerts: concerts)
                return .result()
            }   
        }
    • 15:24 - Request calendar access and fetch upcoming concerts

      // Request calendar access and fetch upcoming concerts
        import EventKit
        
        @Observable
        class UpcomingConcertManager {
            private let eventStore = EKEventStore()
            var upcomingConcerts: [EKEvent] = []
            var authorizationStatus: EKAuthorizationStatus = .notDetermined
            
            func requestAccessAndFetch() async throws {
                let granted = try await eventStore.requestFullAccessToEvents()
                guard granted else {
                    authorizationStatus = .denied
                    return
                }   
                authorizationStatus = .fullAccess
                await fetchUpcomingConcerts()
      
                // ...
            }
        }
    • 15:42 - Filter for upcoming events that match known artists in our catalog

      // Filter for upcoming events that match known artists in our catalog
        class UpcomingConcertManager {
            func fetchUpcomingConcerts() async {
                let predicate = eventStore.predicateForEvents(
                    withStart: .now,
                    end: .now.addingTimeInterval(90 * 24 * 60 * 60),
                    calendars: nil
                )   
                
                let events = eventStore.events(matching: predicate)
                
                upcomingConcerts = events.filter { event in
                    AlbumCatalog.shared.entries.contains { entry in
                        event.title?.localizedCaseInsensitiveContains(entry.album.artistName) == true
                    }
                }
            }
        }
    • 15:44 - Observe newly created events

      // Observe newly created events
        @Observable
        class UpcomingConcertManager {
            // ...
      
            func requestAccessAndFetch() async throws {
                // ...
      
                for await _ in NotificationCenter.default
                    .notifications(
                        named: .EKEventStoreChanged
                    ) {
                    await fetchUpcomingConcerts()
                }
            }
        }
    • 0:07 - Introduction
    • Visual Intelligence integration and what's new in iOS 26, iPadOS, and macOS, using a sample music-discovery app built throughout the session. Outlines the agenda: defining content, implementing a query, cross-platform adoption, and system store integrations.

    • 2:02 - Defining your content
    • Model your app's content as an AppEntity so Visual Intelligence can display it in search results. Covers the entity's DisplayRepresentation (title, subtitle, thumbnail) and best practices around concise identifying text and thumbnail-sized images.

    • 5:03 - Implementing a query
    • IntentValueQuery returns results from a SemanticContentDescriptor's pixel buffer — using the Vision framework's GenerateImageFeaturePrintRequest for on-device image similarity, with pre-computed feature prints and distance thresholds to keep results fast.

    • 8:18 - Opening results
    • Implement an OpenIntent to take people straight to the selected content. Keep it lightweight since it runs as the app foregrounds, and reuse an existing OpenIntent rather than creating one specific to Visual Intelligence.

    • 10:03 - Mac and iPad adoption
    • The same entities, query, and OpenIntent carry over to iPadOS and macOS with minimal changes. Account for platform differences such as camera versus screenshot input and the much larger pixel buffers on Mac that may need resizing.

    • 12:27 - Returning multiple result types
    • The @UnionValue type returns more than one entity type from a single query — here albums plus nearby concerts — encouraging you to derive related content rather than only matching pixels.

    • 12:56 - Continuing search in your app
    • The semanticContentSearch schema lets people continue into your full in-app search — pre-populating results from the captured context so they land on filters, categories, and deeper content.

    • 14:27 - System store integrations
    • Visual Intelligence can also write data your app reads back via system stores: events through EventKit (EKEventStore), contacts via CNContactStore, and medical-device readings via HealthKit (HKHealthStore). Observe store-change notifications so captured data appears automatically.

    • 17:16 - Next steps
    • Recaps the two integration points, Image Search and system stores, across iOS, iPadOS, and macOS. Points to documentation and related App Intents and Vision sessions.

Developer Footer

  • 비디오
  • WWDC26
  • 앱에 시각 지능을 통합하기 위한 모범 사례
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • Apple Intelligence
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • Mini Apps Partner Program
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    최신 뉴스 읽기.
    Apple Developer 앱 받기.
    Copyright © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침