audio-streaming
Receive synchronized PCM audio frames through a Camera stream on iOS
Building a complete DAT app with camera streaming and photo capture
$ npx -y skills add facebook/meta-wearables-dat-ios --skill sample-app-guide --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/sample-app-guideContext preview
The summary Claude sees to decide when to auto-load this skill.
Building a complete DAT app with camera streaming and photo capture
name: sample-app-guide description: Building a complete DAT app with camera streaming and photo capture
Build an iOS DAT app with camera streaming and photo capture.
This walkthrough covers app setup, registration, streaming, and capture. Pair it with the [CameraAccess sample](https://github.com/facebook/meta-wearables-dat-ios/tree/main/samples).
1. Create a new Xcode project (SwiftUI App) 2. Add the SDK via SPM: `https://github.com/facebook/meta-wearables-dat-ios` 3. Add `MWDATCore`, `MWDATCamera`, and `MWDATMockDevice` to your target 4. Configure `Info.plist` (see [Getting Started](getting-started.md))
A typical DAT app has these components:
MyDATApp/
├── MyDATApp.swift # App entry point, SDK init
├── ViewModels/
│ ├── WearablesViewModel.swift # Registration, device management
│ └── StreamViewModel.swift # Streaming, photo capture
└── Views/
├── MainAppView.swift # Navigation
├── RegistrationView.swift # Registration UI
└── StreamView.swift # Video preview, capture buttonimport MWDATCore
@main
struct MyDATApp: App {
init() {
do {
try Wearables.configure()
} catch {
assertionFailure("Wearables SDK configuration failed: \(error)")
}
}
var body: some Scene {
WindowGroup {
MainAppView()
.onOpenURL { url in
guard
let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
components.queryItems?.contains(where: { $0.name == "metaWearablesAction" }) == true
else {
return
}
Task {
_ = try? await Wearables.shared.handleUrl(url)
}
}
}
}
}`devicesStream()` yields `[DeviceIdentifier]` (a `[String]`), not device objects. Resolve each identifier with `wearables.deviceForIdentifier(_:)` when you need `nameOrId()`, `deviceType()`, `linkState`, or `compatibility()`.
import MWDATCore
@MainActor
class WearablesViewModel: ObservableObject {
@Published var registrationState: RegistrationState
@Published var devices: [DeviceIdentifier] = []
private let wearables = Wearables.shared
init() {
registrationState = Wearables.shared.registrationState
}
func observeState() {
Task {
for await state in wearables.registrationStateStream() {
self.registrationState = state
}
}
Task {
for await deviceIds in wearables.devicesStream() {
self.devices = deviceIds
}
}
}
func register() async {
try? await wearables.startRegistration()
}
func unregister() async {
try? await wearables.startUnregistration()
}
}import MWDATCamera
import MWDATCore
@MainActor
class StreamViewModel: ObservableObject {
@Published var currentFrame: UIImage?
@Published var streamState: String = "Stopped"
@Published var capturedPhoto: Data?
private let wearables = Wearables.shared
private var deviceSession: DeviceSession?
private var camera: Camera?
private var stream: Stream?
func startStream() async {
let config = StreamConfiguration(
videoCodec: .raw,
resolution: .medium,
frameRate: 24
)
let selector = AutoDeviceSelector(wearables: wearables)
do {
let deviceSession = try wearables.createSession(deviceSelector: selector)
try deviceSession.start()
// Wait for the device session to reach the started state
for await state in deviceSession.stateStream() {
if state == .started { break }
}
guard let camera = try deviceSession.addCamera(config: config) else { return }
self.deviceSession = deviceSession
self.camera = camera
self.stream = camera.stream
} catch {
return
}
guard let stream else { return }
_ = stream.statePublisher.listen { [weak self] state in
Task { @MainActor in
self?.streamState = "\(state)"
}
}
_ = stream.videoFramePublisher.listen { [weak self] frame in
guard let image = frame.makeUIImage() else { return }
Task { @MainActor in
self?.currentFrame = image
}
}
_ = stream.photoDataPublisher.listen { [weak self] photoData in
Task { @MainActor in
self?.capturedPhoto = photoData.data
}
}
stream.start()
}
func stopStream() {
// Stopping the camera cascades to its stream child
camera?.stop()
deviceSession?.stop()
stream = nil
camera = nil
deviceSession = nil
}
func capturePhoto() {
stream?.capturePhoto(format: .jpeg)
}
}The Meta Wearables Device Access Toolkit enables developers to utilize Meta's AI glasses to build hands-free wearable experiences into their mobile applications.
Receive synchronized PCM audio frames through a Camera stream on iOS
Capture standalone high-quality photos from connected glasses on iOS
Stream, video frames, photo capture, resolution/frame rate configuration
Swift patterns, async/await, naming conventions, key types for DAT SDK iOS development
Use the Wearables DAT MCP server for live DAT documentation search with `search_dat_docs`,…