sample-app-guide

Creación de una aplicación DAT completa con transmisión de cámara y captura de fotos

npx skills add https://github.com/facebook/meta-wearables-dat-ios --skill sample-app-guide

Sample App Guide (iOS)

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.

Project setup

  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)

App architecture

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 button

SDK initialization

import 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
                    Task {
                        _ = try? await Wearables.shared.handleUrl(url)
                    }
                }
        }
    }
}

Wearables ViewModel

import MWDATCore

@MainActor
class WearablesViewModel: ObservableObject {
    @Published var registrationState: String = "Unknown"
    @Published var devices: [DeviceIdentifier] = []

    private let wearables = Wearables.shared

    func observeState() {
        Task {
            for await state in wearables.registrationStateStream() {
                self.registrationState = "\(state)"
            }
        }
        Task {
            for await devices in wearables.devicesStream() {
                self.devices = devices.map { $0.identifier }
            }
        }
    }

    func register() async {
        try? await wearables.startRegistration()
    }

    func unregister() async {
        try? await wearables.startUnregistration()
    }
}

Stream ViewModel

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 }
            let stream = camera.stream
            self.deviceSession = deviceSession
            self.camera = camera
            self.stream = 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() {
        camera?.stop()
        deviceSession?.stop()
        stream = nil
        camera = nil
        deviceSession = nil
    }

    func capturePhoto() {
        stream?.capturePhoto(format: .jpeg)
    }
}

Testing with MockDeviceKit

Add mock device support to develop without glasses:

import MWDATMockDevice

func setupMockDevice() async {
    let mockDeviceKit = MockDeviceKit.shared
    mockDeviceKit.enable()

    guard let device = try? mockDeviceKit.pairGlasses(model: .rayBanMeta) else { return }
    device.don()

    if let videoURL = Bundle.main.url(forResource: "test_video", withExtension: "mov") {
        let camera = device.services.camera
        camera.setCameraFeed(fileURL: videoURL)
    }
}

func tearDownMockDevice() {
    MockDeviceKit.shared.disable()
}

Allowed dependencies

Your DAT app should only depend on:

  • MWDATCore — always required
  • MWDATCamera — for camera streaming
  • MWDATMockDevice — for testing (can be test-only dependency)

Links

Más skills de facebook

api-health
facebook
Monitor API health for a Meta app — check rate limits, call volume, and API deprecations. Use to diagnose throttling, plan capacity, or prepare for API version…
official
api-integration
facebook
Guide a developer through setting up a Meta API integration from scratch — discovers the right APIs, fetches setup guides, authentication requirements,…
official
app-review-prep
facebook
Prepara una app de Meta para App Review: comprueba el estado actual, los requisitos pendientes, los privilegios concedidos y el historial de envíos. Úsalo antes de enviar una app…
official
debug-webhooks
facebook
Troubleshoot webhook issues for a Meta app — inspect active subscriptions, identify misconfiguration, and send test payloads to verify delivery. Use when…
official
webhook-setup
facebook
Configura webhooks para una app de Meta de principio a fin: descubre los temas disponibles, suscríbete a campos y verifica con una carga de prueba. Úsalo al configurar webhooks para…
official
buck2-rule-basics
facebook
Guía a los usuarios en la escritura de su primera regla de Buck2 para aprender conceptos fundamentales, incluyendo reglas, acciones, targets, configuraciones, análisis y select(). Usa…
official
add-ir-instruction
facebook
Guía para añadir una nueva instrucción IR al compilador Hermes. Se utiliza cuando el usuario pide añadir, crear o definir una nueva instrucción IR (Inst/Instruction) en el…
official
binary-size-analysis
facebook
This skill should be used when the user wants to analyze hermesvm binary size changes across a range of commits. Use when the user mentions "binary size",…
official