Highlight
visionOS 26 把 UVC 视频与 Neural Engine 访问开放给所有开发者,并新增 Window Follow Mode、共享坐标空间、内容防截屏与 Camera Region 四类企业 API。
核心内容
去年 visionOS 首次为企业客户开放底层能力,但代价并不小:要拿 UVC 摄像头视频,得申请 managed entitlement、配许可证文件,连 Neural Engine 都得走企业流程。一个想用 USB 摄像头做远程诊断的小团队,光是审批就要走完整套企业开发者合规流程。
visionOS 26 把这条线松开了。Apple 工程师 Alex Powers 在 session 里宣布,UVC 视频访问和 Neural Engine 访问今年全员可用,不再需要企业许可证或 entitlement。对象跟踪从只能在 CreateML app 里点点点,扩展到命令行训练,可以直接接进 CI 管线。许可证管理也搬到了 Apple Developer 账户里,续期通过 OTA 推送给设备。
剩下的企业级能力分成两条线:用户体验侧,多了 Window Follow Mode(窗口跟人走)、SharedCoordinateSpaceProvider(同房间多台 Vision Pro 对齐坐标系)、contentCaptureProtected(敏感内容自动从录屏/共享中遮蔽)。环境可视化侧,Camera Frame Provider 能拿左右单独摄像头或立体声,新增的 Camera Region API 可以把现实世界一小块区域单独抠出来放大、增强对比度,做远程仪表读数这类场景。
详细内容
命令行训练对象跟踪模型(03:00)
xcrun createml objecttracker -s my.usdz -o my.referenceobject
关键点:
xcrun createml objecttracker:调用 CreateML 的对象跟踪子命令,与 GUI 版的 CreateML app 共享同一套训练参数。-s my.usdz:输入的 USDZ 模型文件,用来生成对象的 reference object。-o my.referenceobject:输出资产路径,可以直接接进自动化流水线,按文件批处理。
VisionEntitlementServices 检查许可状态(04:28)
import VisionEntitlementServices
func checkLicenseStatus() {
let license = EnterpriseLicenseDetails.shared
guard license.licenseStatus == .valid else {
print("Enterprise license is not valid: \(license.licenseStatus)")
return
}
if license.isApproved(for: .mainCameraAccess) {
print("Main Camera Access approved. Enabling feature...")
} else {
print("Main Camera Access not approved.")
}
}
关键点:
EnterpriseLicenseDetails.shared:单例,封装当前 app 的许可证信息,包括状态和过期时间。licenseStatus == .valid:先确认整体许可证有效,避免在已过期的许可证上继续走企业逻辑。isApproved(for: .mainCameraAccess):按 entitlement 粒度判断是否被授权使用某项企业 API,运行时动态决定是否开启功能。- 该框架还支持
Increased Performance Headroom的 entitlement 校验,在跑高负载任务前先确认权限。
SharedCoordinateSpaceProvider 自定义共享空间(10:04)
import ARKit
class SharedCoordinateSpaceModel {
let arkitSession = ARKitSession()
let sharedCoordinateSpace = SharedCoordinateSpaceProvider()
let worldTracking = WorldTrackingProvider()
func runARKitSession() async {
do {
try await arkitSession.run([sharedCoordinateSpace, worldTracking])
} catch {
reportError("Error: running session: \(error)")
}
}
func pushCoordinateSpaceData(_ data: Data) {
if let coordinateSpaceData = SharedCoordinateSpaceProvider.CoordinateSpaceData(data: data) {
sharedCoordinateSpace.push(data: coordinateSpaceData)
}
}
func pollCoordinateSpaceData() async {
if let coordinateSpaceData = sharedCoordinateSpace.nextCoordinateSpaceData {
// Send my coordinate space data
}
}
func addWorldAnchor(at transform: simd_float4x4) async throws {
let anchor = WorldAnchor(originFromAnchorTransform: transform, sharedWithNearbyParticipants: true)
try await worldTracking.addAnchor(anchor)
}
}
关键点:
SharedCoordinateSpaceProvider与WorldTrackingProvider一起跑在ARKitSession上,复用熟悉的 ARKit data provider 模型。nextCoordinateSpaceData:拉取本机要广播给其他参与者的对齐数据,由开发者自己决定走 TCP/UDP/自有协议。push(data:):把从其他设备网络收到的CoordinateSpaceData喂回 ARKit,用以建立共同坐标系。WorldAnchor(... sharedWithNearbyParticipants: true):给锚点加上共享标记,房间内其他 Vision Pro 看到同一锚点位置一致。eventUpdates异步序列会在参与者加入/离开、共享开关切换时通知 app(10:04)。
contentCaptureProtected 阻止敏感内容外泄(12:50)
struct SecretDocumentView: View {
var body: some View {
VStack {
Text("Secrets")
.font(.largeTitle)
.padding()
SensitiveDataView()
.contentCaptureProtected()
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
}
关键点:
contentCaptureProtected()是 SwiftUI view modifier,需要 protected content entitlement。- 加在哪一层,哪一层就在系统截屏、录屏、Screen Mirroring、SharePlay 中被自动遮蔽。
- 戴着 Vision Pro 的本人仍能看到原始内容,外部观众看到的是模糊或遮挡块。
- 也支持包住整个 RealityKit 场景,不只是 2D 视图。
Camera Region 把现实抠一块出来(16:48 / 21:15)
import SwiftUI
import VisionKit
struct InspectorView: View {
@Environment(CameraFeedDelivery.self) private var cameraFeedDelivery: CameraFeedDelivery
var body: some View {
CameraRegionView(isContrastAndVibrancyEnhancementEnabled: true) { result in
var pixelBuffer: CVReadOnlyPixelBuffer?
switch result {
case .success(let value):
pixelBuffer = value.pixelBuffer
case .failure(let error):
reportError("Failure: \(error.localizedDescription)")
cameraFeedDelivery.stopFeed()
return nil
}
cameraFeedDelivery.frameUpdate(pixelBuffer: pixelBuffer!)
return nil
}
}
}
关键点:
CameraRegionView来自 VisionKit,是高层封装,把窗口当成「指向现实世界一块区域」的取景器。isContrastAndVibrancyEnhancementEnabled: true:开启对比度与色彩增强,适合远处仪表盘、指针读数。- 闭包里收到
pixelBuffer,可送到自己的视频管线(远程协助、OCR、推流)做后续处理。 - 底层 ARKit 等价物是
CameraRegionAnchor(originFromAnchorTransform:width:height:cameraEnhancement:),可指定.stabilization等增强模式,并通过cameraRegionProvider.anchorUpdates(forID:)拿到逐帧像素更新。 - Apple 建议单个
CameraRegionAnchor占可见区域不超过六分之一,否则资源消耗会显著增加。
核心启发
-
把 USB 摄像头玩出花:UVC 视频访问今年向所有开发者开放,不再需要企业许可证。
- 为什么值得做:之前被许可证劝退的团队现在可以直接接入工业相机、热成像、显微镜等专业设备。
- 怎么开始:拿到 Vision Pro Developer Strap,按 Building spatial experiences for business apps 文档接入 UVC API,先打通最简单的 webcam 视频流再加业务逻辑。
-
用命令行批量训练对象跟踪模型:
xcrun createml objecttracker让模型训练可以脚本化。- 为什么值得做:原本一个产品 SKU 一个 USDZ 一次手动点击,现在可以写一个 shell 脚本跑完几十个对象,CI 里自动产出 referenceobject。
- 怎么开始:参考 Implementing object tracking in your app,在 CI 容器里安装 Xcode command line tools,把 USDZ 输入与 referenceobject 输出接进 artifact 流程。
-
给敏感视图统一加上
contentCaptureProtected():一行 modifier 控制截屏/录屏/共享行为。- 为什么值得做:金融、医疗、设计稿等场景做合规时,最大的痛点是「员工无意中开了 SharePlay/录屏」。这个 API 把控制收归到 SwiftUI 视图层。
- 怎么开始:先列出所有展示敏感数据的子视图,统一封装一个
SensitiveContentwrapper,内部加.contentCaptureProtected(),并在企业开发者后台申请 protected content entitlement。
-
本地网络的多人 Vision Pro 协作:用
SharedCoordinateSpaceProvider在自有网络上跑共享坐标空间。- 为什么值得做:SharePlay 走 iCloud 太重,工厂、医院这类内网封闭场景需要完全本地的协作通道。新 ARKit API 把网络层完全交给开发者。
- 怎么开始:在 ARKitSession 里同时启动
SharedCoordinateSpaceProvider和WorldTrackingProvider,用 Bonjour + UDP 在局域网里双向交换CoordinateSpaceData,再加共享 WorldAnchor。
关联 Session
- Share visionOS experiences with nearby people — SharePlay 高级 API 实现就近设备共享空间体验。
- Discover Apple-Hosted Background Assets — Apple 托管的后台资源下载,企业 app 资产分发可以借鉴。
- Get started with HealthKit in visionOS — visionOS 上的另一类敏感数据访问场景,对照本场看权限设计。
- Explore spatial accessory input on visionOS — visionOS 26 输入设备扩展,与 Window Follow Mode 配合做企业现场场景。
评论
GitHub Issues · utterances