WWDC Quick Look 💓 By SwiftGGTeam
What's new in VisionKit

What's new in VisionKit

观看原视频

Highlight

VisionKit 在 iOS 17 和 macOS Sonoma 中新增了 Subject Lifting(主体提取)和 Visual Look Up(视觉查找)两项核心能力,DataScannerViewController 增加了光学流追踪和货币识别,macOS 原生 App 可以通过 ImageAnalysisOverlayView 集成 Live Text、Subject Lifting 和 Visual Look Up,且大部分功能对已接入图像分析 API 的 App 自动生效、无需代码改动。


核心内容

问题:图片中的信息难以直接利用

用户在 App 中看到一张图片,想提取其中的文字、识别图中的物体、或者把某个主体单独拿出来分享。传统做法需要开发者自己集成复杂的计算机视觉模型,处理不同场景的边缘情况。

VisionKit 在 WWDC22 引入了 Live Text 和 DataScanner,让这些问题有了系统级解决方案。WWDC23 在此基础上扩展了三项能力:

  1. Subject Lifting:长按提取图片中的主体,支持创建贴纸
  2. Visual Look Up:识别宠物、植物、地标、艺术品等,新增食物、产品和标志符号
  3. macOS 原生支持:Catalyst 和原生 macOS App 都可以使用 VisionKit

详细内容

Subject Lifting 自动可用(01:13

如果你已经在使用 VisionKit 的图像分析 API,Subject Lifting 已经自动启用:

import VisionKit

let analyzer = ImageAnalyzer()
let interaction = ImageAnalysisInteraction()

// 分析图像
let configuration = ImageAnalyzer.Configuration([
    .text,
    .machineReadableCodes
])

let analysis = try? await analyzer.analyze(image, configuration: configuration)
interaction.analysis = analysis
imageView.addInteraction(interaction)

关键点:

  • 不需要修改现有代码,Subject Lifting 自动生效
  • 分析配置中不需要添加特殊参数
  • Subject Lifting 的分析在初始分析完成后延迟执行,节省电量
  • iOS 上在图片显示几秒后触发,macOS 上在首次显示菜单时触发

控制交互类型(02:38

// 仅启用 Subject Lifting,不包含文本选择
interaction.preferredInteractionTypes = .imageSegmentation

// 组合多种交互类型
interaction.preferredInteractionTypes = [.imageSegmentation, .textSelection]

// 保持 iOS 16 的自动行为(文本 + 二维码,不含 Subject Lifting)
interaction.preferredInteractionTypes = .automaticTextOnly

// 默认:包含所有功能
interaction.preferredInteractionTypes = .automatic

关键点:

  • .automatic 包含文本选择、Subject Lifting、数据检测器等所有功能
  • .imageSegmentation 只启用主体提取
  • .automaticTextOnly 保持 iOS 16 的行为,不包含 Subject Lifting
  • 可以用数组组合多种类型

Visual Look Up(03:23

Visual Look Up 支持识别以下类别:

  • 原有类别:宠物、自然(植物/花卉)、地标、艺术品、媒体
  • iOS 17 新增:食物、产品、标志和符号

启用 Visual Look Up 需要在分析配置中添加 .visualLookUp

let configuration = ImageAnalyzer.Configuration([
    .text,
    .visualLookUp
])

let analysis = try? await analyzer.analyze(image, configuration: configuration)
interaction.analysis = analysis

关键点:

  • Visual Look Up 的处理分为两个阶段
  • 第一阶段完全在设备上完成:定位结果边界框、确定顶级类别(如猫、书、植物)、提取特征
  • 第二阶段仅在用户请求时联网:将类别和图像嵌入发送到服务器获取详细信息
  • 隐私保护:设备只发送特征嵌入,不发送原始图像

Visual Look Up 的两种交互模式(04:40

模式一:与 Subject Lifting 联动

如果提取的主体恰好只有一个关联的 Visual Look Up 结果,菜单中会显示 “Look Up” 选项。VisionKit 自动处理这个交互。

模式二:模态徽章模式

// 将 Visual Look Up 设为首选交互类型
interaction.preferredInteractionTypes = .visualLookUp

关键点:

  • 图片上会显示徽章标记每个视觉搜索结果
  • 徽章在移出视口时会自动移到角落
  • 用户点击徽章查看 Look Up 结果
  • 这种模式会覆盖其他交互类型(不能同时选中文本)
  • 通常配合按钮使用,让用户主动进入/退出此模式

DataScannerViewController 增强(06:03

光学流追踪:让实时摄像头中的文字高亮更加稳定。

let scanner = DataScannerViewController(
    recognizedDataTypes: [.text()],
    qualityLevel: .balanced,
    recognizesMultipleItems: true,
    isHighFrameRateTrackingEnabled: true  // 默认已启用
)

关键点:

  • 光学流追踪自动启用,无需额外代码
  • 仅在识别文本时可用,不适用于二维码
  • 需要不指定具体的文本内容类型
  • highFrameRateTracking 默认开启

货币识别

let scanner = DataScannerViewController(
    recognizedDataTypes: [
        .text(textContentType: .currency)
    ]
)

// 处理识别结果
for await item in scanner.recognizedItems {
    if case .text(let text) = item {
        let transcript = text.transcript  // 例如 "$12.99"
        // transcript 包含货币符号和金额
    }
}

关键点:

  • textContentType: .currency 启用货币识别
  • 识别结果包含货币符号和金额文本
  • 可以结合当前 locale 解析具体的货币值

Live Text 增强(08:27

新增语言支持:泰语和越南语。

表格检测:Live Text 现在支持检测和提取图片中的表格结构。

// 用户选中表格区域后复制
// 粘贴到 Numbers 或 Notes 时,表格结构自动保留
// 包括单元格合并等复杂结构

上下文感知数据检测器

当用户从图片中添加联系人时,系统会自动提取周围相关的数据检测器信息(如电话号码、地址),一并填入联系人卡片。

新的文本选择 API(10:04

// 获取选中的纯文本
let selectedText = interaction.selectedText

// 获取带属性的文本
let selectedAttributedText = interaction.selectedAttributedText

// 获取选中的范围
let selectedRange = interaction.selectedRange

// 监听选择变化
func imageAnalysisInteraction(
    _ interaction: ImageAnalysisInteraction,
    didUpdateSelectionWithText selectedText: String?
) {
    // 更新 UI,例如启用/禁用自定义菜单项
}

关键点:

  • selectedText 返回纯文本字符串
  • selectedAttributedText 返回带格式的 NSAttributedString
  • selectedRange 返回在分析文本中的范围
  • 新的 delegate 方法在选择变化时回调

自定义菜单(10:31

override func buildMenu(with builder: UIMenuBuilder) {
    super.buildMenu(with: builder)
    
    // 获取当前选中的文本
    guard let selectedText = interaction.selectedText,
          !selectedText.isEmpty else { return }
    
    // 创建自定义命令
    let createReminderAction = UIAction(title: "Create Reminder") { _ in
        // 用选中的文本创建提醒事项
        self.createReminder(with: selectedText)
    }
    
    // 创建菜单
    let reminderMenu = UIMenu(title: "", children: [createReminderAction])
    
    // 插入到系统菜单之后
    builder.insertSibling(reminderMenu, afterMenu: .share)
}

关键点:

  • 使用 UIMenuBuilder API 插入自定义菜单项
  • 可以基于当前选中的文本动态创建菜单
  • 自定义菜单与系统菜单(复制、分享等)并排显示

macOS Catalyst 支持(11:08

Catalyst App 只需重新编译即可获得 VisionKit 支持:

  • 支持 Live Text、Subject Lifting、Visual Look Up
  • 不支持二维码扫描(.machineReadableCodes 在 Catalyst 上为 no-op)
  • 保留 .machineReadableCodes 在配置中是安全的,不会报错

macOS 原生 API:ImageAnalysisOverlayView(12:14

原生 macOS App 使用 ImageAnalysisOverlayView

import VisionKit

// 分析图像(与 iOS 相同)
let analyzer = ImageAnalyzer()
let configuration = ImageAnalyzer.Configuration([.text, .visualLookUp])
let analysis = try? await analyzer.analyze(image, configuration: configuration)

// 创建叠加视图
let overlayView = ImageAnalysisOverlayView()
overlayView.analysis = analysis

// 添加到视图层级
imageView.addSubview(overlayView)

// 如果使用 NSImageView,设置 trackingImageView 自动计算 contentsRect
overlayView.trackingImageView = imageView

// 如果不使用 NSImageView,手动提供 contentsRect
extension ViewController: ImageAnalysisOverlayViewDelegate {
    func contentsRect(for overlayView: ImageAnalysisOverlayView) -> CGRect {
        // 返回图像内容在 overlayView 坐标系中的位置
        return imageContentRect
    }
}

关键点:

  • ImageAnalysisOverlayViewNSView 的子类
  • 需要添加到图像内容之上
  • trackingImageView 属性自动处理 contentsRect 计算
  • contentsRect 使用单位坐标系(左上角为原点)

macOS 上下文菜单集成(15:13

extension ViewController: ImageAnalysisOverlayViewDelegate {
    func overlayView(
        _ overlayView: ImageAnalysisOverlayView,
        updatedMenu menu: NSMenu,
        for event: NSEvent,
        at point: CGPoint
    ) -> NSMenu {
        
        // 获取 VisionKit 菜单项
        let copySubjectItem = menu.item(withTag: ImageAnalysisOverlayView.MenuItemTag.copySubject.rawValue)
        
        // 添加到自己的菜单中
        let myMenu = NSMenu()
        myMenu.addItem(copySubjectItem!)
        
        // 或者修改菜单项标题
        copySubjectItem?.title = "Copy Photo"
        
        // 或者将自定义项插入 VisionKit 菜单
        let myItem = NSMenuItem(title: "My Custom Action", action: #selector(customAction), keyEquivalent: "")
        if let recommendedIndex = menu.indexOfItem(withTag: ImageAnalysisOverlayView.MenuItemTag.recommendedAppItems.rawValue) {
            menu.insertItem(myItem, at: recommendedIndex)
        }
        
        return menu
    }
}

关键点:

  • updatedMenu:forEvent:atPoint: 允许你修改或替换右键菜单
  • VisionKit 菜单项通过 MenuItemTag 标识
  • recommendedAppItems 标签标识了推荐插入自定义项的位置
  • 菜单项每次都会重新创建,可以安全修改属性
  • VisionKit 会自动处理菜单高亮时的主体提取动画

核心启发

  1. 为相册 App 添加一键主体提取分享:如果你的 App 显示图片,将 ImageAnalysisInteractionpreferredInteractionTypes 设为 .automatic,用户长按即可提取主体并分享。为什么值得做:主体提取是 iOS 17 的标志性功能,用户已经熟悉这个交互。你的 App 支持后,用户体验与系统 Photos app 一致。怎么开始:确认已有图像分析代码,将 preferredInteractionTypes.automaticTextOnly 改为 .automatic

  2. 为购物 App 集成 Visual Look Up:在商品图片上启用 Visual Look Up,让用户识别产品并获取更多信息。为什么值得做:Visual Look Up 支持产品识别,用户可以直接从图片中了解商品详情,减少搜索步骤。怎么开始:在 ImageAnalyzer.Configuration 中添加 .visualLookUp,设置 preferredInteractionTypes = .visualLookUp 配合按钮进入徽章模式。

  3. 为记账 App 添加收据扫描:用 DataScannerViewController 的货币识别功能,自动提取收据上的金额并汇总。为什么值得做:手动输入收据金额繁琐且容易出错。DataScanner 可以实时识别货币值,结合光学流追踪,高亮稳定不抖动。怎么开始:创建 DataScannerViewController,设置 recognizedDataTypes.text(textContentType: .currency),在 recognizedItems 流中累加金额。

  4. 为 macOS 图片编辑器添加 Live Text:用 ImageAnalysisOverlayView 让 macOS App 支持图片中的文本选择和复制。为什么值得做:macOS 用户习惯右键菜单操作,Live Text 让图片中的文字可以直接编辑,无需 OCR 预处理。怎么开始:创建 ImageAnalysisOverlayView,设置为 imageView 的子视图,设置 trackingImageView 属性,实现 overlayView:updatedMenu:forEvent:atPoint: delegate 方法自定义菜单。


关联 Session

评论

GitHub Issues · utterances