[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-meta-display-access":3,"mdc--lek0zg-key":40,"related-repo-meta-display-access":2294,"related-org-meta-display-access":2388},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":29,"repoUrl":30,"updatedAt":31,"license":32,"forks":33,"topics":34,"repo":35,"sourceUrl":38,"mdContent":39},"display-access","manage display capabilities on wearable devices","Display capability setup, display-capable device selection, UI DSL, icons, buttons, images, and video playback",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"meta","Meta Open Source","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmeta.png","facebook",[13,17,20,23,26],{"name":14,"slug":15,"type":16},"Interaction","interaction","tag",{"name":18,"slug":19,"type":16},"Images","images",{"name":21,"slug":22,"type":16},"Video","video",{"name":24,"slug":25,"type":16},"UI Components","ui-components",{"name":27,"slug":28,"type":16},"Design","design",488,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-dat-ios","2026-05-15T06:14:39.844502",null,112,[],{"repoUrl":30,"stars":29,"forks":33,"topics":36,"description":37},[],"Meta Wearables Device Access Toolkit for iOS","https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-dat-ios\u002Ftree\u002FHEAD\u002Fplugins\u002Fmwdat-ios\u002Fskills\u002Fdisplay-access","---\nname: display-access\ndescription: Display capability setup, display-capable device selection, UI DSL, icons, buttons, images, and video playback\n---\n\n# Display Access (iOS)\n\nUse `MWDATDisplay` to render content on Meta Ray-Ban Display glasses.\n\nUse this skill with `getting-started` and `permissions-registration` when creating a full app. A Display app still needs `Wearables.configure()` at launch, Info.plist URL scheme configuration, URL callbacks through `Wearables.shared.handleUrl(_:)`, and completed Meta AI registration before it can create a session.\n\n## Add the Display module\n\nAdd `MWDATDisplay` to the same app target that already uses `MWDATCore`. Import it next to core:\n\n```swift\nimport MWDATCore\nimport MWDATDisplay\n```\n\n## Display-specific app configuration\n\nUse the getting-started Info.plist setup, then mirror the DisplayAccess sample for Display sessions:\n\n- Keep the `CFBundleURLTypes` URL scheme and route callbacks to `Wearables.shared.handleUrl(_:)`.\n- Under `MWDAT`, set `AppLinkURLScheme`, `MetaAppID`, `ClientToken`, `TeamID`, and `DAMEnabled = true`. `MetaAppID = 0` is for Developer Mode; production apps should use Wearables Developer Center values for `MetaAppID` and `ClientToken`, plus the Apple Developer Team ID.\n- Include `UISupportedExternalAccessoryProtocols` with `com.meta.ar.wearable`, `UIBackgroundModes` entries for `external-accessory` and `bluetooth-central`, and `NSBluetoothAlwaysUsageDescription`. The DisplayAccess sample also includes `bluetooth-peripheral` and `processing`.\n- For high-bandwidth Display\u002Fvideo fallback, include a non-empty `NSLocalNetworkUsageDescription` and `NSBonjourServices`. Display acquires link leases: core device discovery\u002Fsession setup uses medium then low links, while Display uses medium then high links when available.\n\n## Select a display-capable device\n\nUse the public display filter when creating an automatic selector:\n\n```swift\nlet wearables = Wearables.shared\nlet deviceSelector = AutoDeviceSelector(\n  wearables: wearables,\n  filter: { device in device.supportsDisplay() }\n)\n```\n\nUse `SpecificDeviceSelector(device: selectedDevice.identifier)` instead when your UI lets the user pick a specific `Device`. The initializer takes a `DeviceIdentifier`, not the whole `Device`.\n\n`AutoDeviceSelector` updates from `devicesStream()`. Create it before the user taps the Display action, or wait for `activeDeviceStream()` to yield a non-nil device before calling `createSession(deviceSelector:)`; otherwise `createSession` can throw `DeviceSessionError.noEligibleDevice`.\n\nFor a picker or Settings screen, list devices from `Wearables.shared.devicesStream()`, then look up metadata from `deviceForIdentifier(_:)`. The DisplayAccess sample shows `nameOrId()`, `deviceType().rawValue`, `linkState`, and `compatibility()` and keeps `addLinkStateListener` \u002F `addCompatibilityListener` tokens alive while rows are visible. If `compatibility() == .deviceUpdateRequired`, surface a firmware update action through `Wearables.shared.openFirmwareUpdate()`.\n\n## Attach Display after the session starts\n\nCreate and start the `DeviceSession`, wait for `.started`, then add and start `Display`. Keep the state listener token alive for as long as you need updates, and observe `session.errorStream()` for async session failures.\n\n```swift\nimport MWDATCore\nimport MWDATDisplay\n\n@MainActor\nfinal class DisplayController {\n  private var deviceSession: DeviceSession?\n  private var display: Display?\n  private var displayStateToken: AnyListenerToken?\n  private var sessionErrorTask: Task\u003CVoid, Never>?\n\n  func connect() async {\n    do {\n      let wearables = Wearables.shared\n      let selector = AutoDeviceSelector(\n        wearables: wearables,\n        filter: { $0.supportsDisplay() }\n      )\n\n      let session = try wearables.createSession(deviceSelector: selector)\n      deviceSession = session\n      sessionErrorTask = Task { [weak self] in\n        for await error in session.errorStream() {\n          await self?.showError(error.localizedDescription)\n        }\n      }\n\n      let sessionStarted = Task {\n        for await state in session.stateStream() {\n          if state == .started {\n            return\n          }\n        }\n      }\n      do {\n        try session.start()\n        await sessionStarted.value\n      } catch {\n        sessionStarted.cancel()\n        throw error\n      }\n\n      let capability = try session.addDisplay()\n      display = capability\n      displayStateToken = capability.statePublisher.listen { [weak self] state in\n        Task { @MainActor in\n          if state == .started {\n            self?.showStatusCard()\n          }\n        }\n      }\n\n      capability.start()\n    } catch DeviceSessionError.datAppOnTheGlassesUpdateRequired {\n      showDATGlassesAppUpdate()\n    } catch {\n      showError(error.localizedDescription)\n    }\n  }\n\n  func disconnect() async {\n    display?.onPlaybackEvent = nil\n    display?.stop()\n    deviceSession?.stop()\n    sessionErrorTask?.cancel()\n    sessionErrorTask = nil\n    displayStateToken = nil\n    display = nil\n    deviceSession = nil\n  }\n}\n```\n\nFor user-triggered content, match the sample's pending-action pattern: if the user taps \"Try it\" before Display is connected, store the send as a pending async action, attach to Display, and run the action when `DisplayState.started` arrives. Reset the display session when registration changes to `.available` or `.unavailable`.\n\n## Send display UI\n\nBuild exactly one root `DisplayableView` per `send(_:)` call. Each send replaces the previous content on the glasses and replaces the active tap handlers. Use a root `FlexBox` for UI, or a root `VideoPlayer` for video. Do not send `Text`, `Button`, `Image`, or `Icon` as the root; place them inside a `FlexBox`.\n\nIf a file also imports SwiftUI, Display DSL names such as `Text`, `Button`, and `Image` can be ambiguous. Prefer keeping Display builders in files that import `MWDATDisplay` without SwiftUI, or qualify the symbols as `MWDATDisplay.Text`, `MWDATDisplay.Button`, and `MWDATDisplay.Image`.\n\n```swift\nfunc showStatusCard() {\n  Task {\n    do {\n      try await display?.send(\n        FlexBox(direction: .column, spacing: 12) {\n          Text(\"Bike ride\", style: .heading)\n          Text(\"Turn right in 200 ft\", style: .body, color: .secondary)\n          Button(\n            label: \"Done\",\n            style: .primary,\n            iconName: .checkmark,\n            onClick: { print(\"Done tapped\") }\n          )\n        }\n        .padding(24)\n        .background(.card)\n        .onTap { print(\"Card tapped\") }\n      )\n    } catch {\n      showError((error as? DisplayError)?.description ?? error.localizedDescription)\n    }\n  }\n}\n```\n\n## Use images and built-in icons\n\nUse HTTPS image URLs for image content, and use the `IconName` enum for built-in icons. Do not invent raw icon strings.\n\n```swift\ntry await display.send(\n  FlexBox(direction: .row, spacing: 8, crossAlignment: .center) {\n    Image(\n      uri: \"https:\u002F\u002Fexample.com\u002Fthumbnail.png\",\n      sizePreset: .fill,\n      cornerRadius: .medium\n    )\n    Icon(name: .gear, style: .filled)\n    Text(\"Device settings\", style: .body)\n  }\n  .padding(24)\n)\n```\n\n## Send video\n\nFor URL-based video, send a root `VideoPlayer`. Use `VideoPlayer(onError:)` for video-specific errors, and use `display.onPlaybackEvent` for playback events. Set `onPlaybackEvent` before sending the video, clear it after terminal events if the flow is complete, and call `sendVideoStop()` if the user exits playback early. Blank or non-HTTP(S) URLs throw `DisplayError.invalidVideoURL`.\n\n```swift\ndisplay.onPlaybackEvent = { event in\n  if event.type == .ended || event.type == .stopped {\n    Task { @MainActor in\n      display.onPlaybackEvent = nil\n      showStatusCard()\n    }\n  }\n}\n\ntry await display.send(\n  VideoPlayer(\n    provider: .uri(\"https:\u002F\u002Fexample.com\u002Ftutorial.mp4\"),\n    codec: .mp4,\n    onError: { error in\n      Task { @MainActor in\n        showError(error.localizedDescription)\n      }\n    }\n  )\n)\n```\n\n## Display rules\n\n- Call `Wearables.configure()` at app launch and complete registration before creating the session.\n- Enable `MWDAT.DAMEnabled` for Display sessions, and include the DisplayAccess sample's link-lease Info.plist keys when building a full Display app.\n- Wait for the `DeviceSession` to reach `.started` before calling `addDisplay()`.\n- Handle `DeviceSessionError.datAppOnTheGlassesUpdateRequired` separately and offer `Wearables.shared.openDATGlassesAppUpdate()`.\n- Call `display.start()`, then wait for `DisplayState.started` through `statePublisher` before sending user-triggered content.\n- Observe `session.errorStream()` so async session failures are surfaced.\n- Keep listener tokens alive; dropping a token stops that listener.\n- Use the getting-started setup for Info.plist URL schemes and route app-open URLs to `Wearables.shared.handleUrl(_:)`.\n- Use `nameOrId()`, `deviceType()`, `linkState`, and `compatibility()` for device rows; keep link\u002Fcompatibility listener tokens until the row is gone.\n- Use `FlexBox.onTap` and `Button(label:onClick:)` for interactions. The callbacks belong to the most recent sent view.\n- Use only public Display DSL names: `FlexBox`, `Text`, `Button`, `Image`, `Icon`, `VideoPlayer`, `IconName`, `TextStyle`, `TextColor`, `ButtonStyle`, `ImageSize`, `CornerRadius`, `Direction`, `Alignment`, `Background`, `Edge`, and `EdgeInsets`.\n- Clear `display.onPlaybackEvent` when the video flow is finished if you no longer need playback callbacks.\n- Stop Display before stopping the parent `DeviceSession` when the display experience ends.\n\n## Sample app\n\nUse the Display Access sample app for a complete flow: registration, device selection, display attachment, interactive content, and video.\n\n## Links\n\n- [iOS API reference](https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Freference\u002Fios_swift\u002Fdat\u002F0.8)\n- [Developer documentation](https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Fdevelop\u002F)\n",{"data":41,"body":42},{"name":4,"description":6},{"type":43,"children":44},"root",[45,54,69,106,113,133,164,170,175,356,362,367,417,451,501,582,588,625,1242,1270,1276,1349,1401,1585,1591,1604,1705,1711,1762,1921,1927,2246,2252,2257,2263,2288],{"type":46,"tag":47,"props":48,"children":50},"element","h1",{"id":49},"display-access-ios",[51],{"type":52,"value":53},"text","Display Access (iOS)",{"type":46,"tag":55,"props":56,"children":57},"p",{},[58,60,67],{"type":52,"value":59},"Use ",{"type":46,"tag":61,"props":62,"children":64},"code",{"className":63},[],[65],{"type":52,"value":66},"MWDATDisplay",{"type":52,"value":68}," to render content on Meta Ray-Ban Display glasses.",{"type":46,"tag":55,"props":70,"children":71},{},[72,74,80,82,88,90,96,98,104],{"type":52,"value":73},"Use this skill with ",{"type":46,"tag":61,"props":75,"children":77},{"className":76},[],[78],{"type":52,"value":79},"getting-started",{"type":52,"value":81}," and ",{"type":46,"tag":61,"props":83,"children":85},{"className":84},[],[86],{"type":52,"value":87},"permissions-registration",{"type":52,"value":89}," when creating a full app. A Display app still needs ",{"type":46,"tag":61,"props":91,"children":93},{"className":92},[],[94],{"type":52,"value":95},"Wearables.configure()",{"type":52,"value":97}," at launch, Info.plist URL scheme configuration, URL callbacks through ",{"type":46,"tag":61,"props":99,"children":101},{"className":100},[],[102],{"type":52,"value":103},"Wearables.shared.handleUrl(_:)",{"type":52,"value":105},", and completed Meta AI registration before it can create a session.",{"type":46,"tag":107,"props":108,"children":110},"h2",{"id":109},"add-the-display-module",[111],{"type":52,"value":112},"Add the Display module",{"type":46,"tag":55,"props":114,"children":115},{},[116,118,123,125,131],{"type":52,"value":117},"Add ",{"type":46,"tag":61,"props":119,"children":121},{"className":120},[],[122],{"type":52,"value":66},{"type":52,"value":124}," to the same app target that already uses ",{"type":46,"tag":61,"props":126,"children":128},{"className":127},[],[129],{"type":52,"value":130},"MWDATCore",{"type":52,"value":132},". Import it next to core:",{"type":46,"tag":134,"props":135,"children":140},"pre",{"className":136,"code":137,"language":138,"meta":139,"style":139},"language-swift shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import MWDATCore\nimport MWDATDisplay\n","swift","",[141],{"type":46,"tag":61,"props":142,"children":143},{"__ignoreMap":139},[144,155],{"type":46,"tag":145,"props":146,"children":149},"span",{"class":147,"line":148},"line",1,[150],{"type":46,"tag":145,"props":151,"children":152},{},[153],{"type":52,"value":154},"import MWDATCore\n",{"type":46,"tag":145,"props":156,"children":158},{"class":147,"line":157},2,[159],{"type":46,"tag":145,"props":160,"children":161},{},[162],{"type":52,"value":163},"import MWDATDisplay\n",{"type":46,"tag":107,"props":165,"children":167},{"id":166},"display-specific-app-configuration",[168],{"type":52,"value":169},"Display-specific app configuration",{"type":46,"tag":55,"props":171,"children":172},{},[173],{"type":52,"value":174},"Use the getting-started Info.plist setup, then mirror the DisplayAccess sample for Display sessions:",{"type":46,"tag":176,"props":177,"children":178},"ul",{},[179,200,272,336],{"type":46,"tag":180,"props":181,"children":182},"li",{},[183,185,191,193,198],{"type":52,"value":184},"Keep the ",{"type":46,"tag":61,"props":186,"children":188},{"className":187},[],[189],{"type":52,"value":190},"CFBundleURLTypes",{"type":52,"value":192}," URL scheme and route callbacks to ",{"type":46,"tag":61,"props":194,"children":196},{"className":195},[],[197],{"type":52,"value":103},{"type":52,"value":199},".",{"type":46,"tag":180,"props":201,"children":202},{},[203,205,211,213,219,221,227,228,234,235,241,243,249,251,257,259,264,265,270],{"type":52,"value":204},"Under ",{"type":46,"tag":61,"props":206,"children":208},{"className":207},[],[209],{"type":52,"value":210},"MWDAT",{"type":52,"value":212},", set ",{"type":46,"tag":61,"props":214,"children":216},{"className":215},[],[217],{"type":52,"value":218},"AppLinkURLScheme",{"type":52,"value":220},", ",{"type":46,"tag":61,"props":222,"children":224},{"className":223},[],[225],{"type":52,"value":226},"MetaAppID",{"type":52,"value":220},{"type":46,"tag":61,"props":229,"children":231},{"className":230},[],[232],{"type":52,"value":233},"ClientToken",{"type":52,"value":220},{"type":46,"tag":61,"props":236,"children":238},{"className":237},[],[239],{"type":52,"value":240},"TeamID",{"type":52,"value":242},", and ",{"type":46,"tag":61,"props":244,"children":246},{"className":245},[],[247],{"type":52,"value":248},"DAMEnabled = true",{"type":52,"value":250},". ",{"type":46,"tag":61,"props":252,"children":254},{"className":253},[],[255],{"type":52,"value":256},"MetaAppID = 0",{"type":52,"value":258}," is for Developer Mode; production apps should use Wearables Developer Center values for ",{"type":46,"tag":61,"props":260,"children":262},{"className":261},[],[263],{"type":52,"value":226},{"type":52,"value":81},{"type":46,"tag":61,"props":266,"children":268},{"className":267},[],[269],{"type":52,"value":233},{"type":52,"value":271},", plus the Apple Developer Team ID.",{"type":46,"tag":180,"props":273,"children":274},{},[275,277,283,285,291,292,298,300,306,307,313,314,320,322,328,329,335],{"type":52,"value":276},"Include ",{"type":46,"tag":61,"props":278,"children":280},{"className":279},[],[281],{"type":52,"value":282},"UISupportedExternalAccessoryProtocols",{"type":52,"value":284}," with ",{"type":46,"tag":61,"props":286,"children":288},{"className":287},[],[289],{"type":52,"value":290},"com.meta.ar.wearable",{"type":52,"value":220},{"type":46,"tag":61,"props":293,"children":295},{"className":294},[],[296],{"type":52,"value":297},"UIBackgroundModes",{"type":52,"value":299}," entries for ",{"type":46,"tag":61,"props":301,"children":303},{"className":302},[],[304],{"type":52,"value":305},"external-accessory",{"type":52,"value":81},{"type":46,"tag":61,"props":308,"children":310},{"className":309},[],[311],{"type":52,"value":312},"bluetooth-central",{"type":52,"value":242},{"type":46,"tag":61,"props":315,"children":317},{"className":316},[],[318],{"type":52,"value":319},"NSBluetoothAlwaysUsageDescription",{"type":52,"value":321},". The DisplayAccess sample also includes ",{"type":46,"tag":61,"props":323,"children":325},{"className":324},[],[326],{"type":52,"value":327},"bluetooth-peripheral",{"type":52,"value":81},{"type":46,"tag":61,"props":330,"children":332},{"className":331},[],[333],{"type":52,"value":334},"processing",{"type":52,"value":199},{"type":46,"tag":180,"props":337,"children":338},{},[339,341,347,348,354],{"type":52,"value":340},"For high-bandwidth Display\u002Fvideo fallback, include a non-empty ",{"type":46,"tag":61,"props":342,"children":344},{"className":343},[],[345],{"type":52,"value":346},"NSLocalNetworkUsageDescription",{"type":52,"value":81},{"type":46,"tag":61,"props":349,"children":351},{"className":350},[],[352],{"type":52,"value":353},"NSBonjourServices",{"type":52,"value":355},". Display acquires link leases: core device discovery\u002Fsession setup uses medium then low links, while Display uses medium then high links when available.",{"type":46,"tag":107,"props":357,"children":359},{"id":358},"select-a-display-capable-device",[360],{"type":52,"value":361},"Select a display-capable device",{"type":46,"tag":55,"props":363,"children":364},{},[365],{"type":52,"value":366},"Use the public display filter when creating an automatic selector:",{"type":46,"tag":134,"props":368,"children":370},{"className":136,"code":369,"language":138,"meta":139,"style":139},"let wearables = Wearables.shared\nlet deviceSelector = AutoDeviceSelector(\n  wearables: wearables,\n  filter: { device in device.supportsDisplay() }\n)\n",[371],{"type":46,"tag":61,"props":372,"children":373},{"__ignoreMap":139},[374,382,390,399,408],{"type":46,"tag":145,"props":375,"children":376},{"class":147,"line":148},[377],{"type":46,"tag":145,"props":378,"children":379},{},[380],{"type":52,"value":381},"let wearables = Wearables.shared\n",{"type":46,"tag":145,"props":383,"children":384},{"class":147,"line":157},[385],{"type":46,"tag":145,"props":386,"children":387},{},[388],{"type":52,"value":389},"let deviceSelector = AutoDeviceSelector(\n",{"type":46,"tag":145,"props":391,"children":393},{"class":147,"line":392},3,[394],{"type":46,"tag":145,"props":395,"children":396},{},[397],{"type":52,"value":398},"  wearables: wearables,\n",{"type":46,"tag":145,"props":400,"children":402},{"class":147,"line":401},4,[403],{"type":46,"tag":145,"props":404,"children":405},{},[406],{"type":52,"value":407},"  filter: { device in device.supportsDisplay() }\n",{"type":46,"tag":145,"props":409,"children":411},{"class":147,"line":410},5,[412],{"type":46,"tag":145,"props":413,"children":414},{},[415],{"type":52,"value":416},")\n",{"type":46,"tag":55,"props":418,"children":419},{},[420,421,427,429,435,437,443,445,450],{"type":52,"value":59},{"type":46,"tag":61,"props":422,"children":424},{"className":423},[],[425],{"type":52,"value":426},"SpecificDeviceSelector(device: selectedDevice.identifier)",{"type":52,"value":428}," instead when your UI lets the user pick a specific ",{"type":46,"tag":61,"props":430,"children":432},{"className":431},[],[433],{"type":52,"value":434},"Device",{"type":52,"value":436},". The initializer takes a ",{"type":46,"tag":61,"props":438,"children":440},{"className":439},[],[441],{"type":52,"value":442},"DeviceIdentifier",{"type":52,"value":444},", not the whole ",{"type":46,"tag":61,"props":446,"children":448},{"className":447},[],[449],{"type":52,"value":434},{"type":52,"value":199},{"type":46,"tag":55,"props":452,"children":453},{},[454,460,462,468,470,476,478,484,486,492,494,500],{"type":46,"tag":61,"props":455,"children":457},{"className":456},[],[458],{"type":52,"value":459},"AutoDeviceSelector",{"type":52,"value":461}," updates from ",{"type":46,"tag":61,"props":463,"children":465},{"className":464},[],[466],{"type":52,"value":467},"devicesStream()",{"type":52,"value":469},". Create it before the user taps the Display action, or wait for ",{"type":46,"tag":61,"props":471,"children":473},{"className":472},[],[474],{"type":52,"value":475},"activeDeviceStream()",{"type":52,"value":477}," to yield a non-nil device before calling ",{"type":46,"tag":61,"props":479,"children":481},{"className":480},[],[482],{"type":52,"value":483},"createSession(deviceSelector:)",{"type":52,"value":485},"; otherwise ",{"type":46,"tag":61,"props":487,"children":489},{"className":488},[],[490],{"type":52,"value":491},"createSession",{"type":52,"value":493}," can throw ",{"type":46,"tag":61,"props":495,"children":497},{"className":496},[],[498],{"type":52,"value":499},"DeviceSessionError.noEligibleDevice",{"type":52,"value":199},{"type":46,"tag":55,"props":502,"children":503},{},[504,506,512,514,520,522,528,529,535,536,542,543,549,551,557,559,565,567,573,575,581],{"type":52,"value":505},"For a picker or Settings screen, list devices from ",{"type":46,"tag":61,"props":507,"children":509},{"className":508},[],[510],{"type":52,"value":511},"Wearables.shared.devicesStream()",{"type":52,"value":513},", then look up metadata from ",{"type":46,"tag":61,"props":515,"children":517},{"className":516},[],[518],{"type":52,"value":519},"deviceForIdentifier(_:)",{"type":52,"value":521},". The DisplayAccess sample shows ",{"type":46,"tag":61,"props":523,"children":525},{"className":524},[],[526],{"type":52,"value":527},"nameOrId()",{"type":52,"value":220},{"type":46,"tag":61,"props":530,"children":532},{"className":531},[],[533],{"type":52,"value":534},"deviceType().rawValue",{"type":52,"value":220},{"type":46,"tag":61,"props":537,"children":539},{"className":538},[],[540],{"type":52,"value":541},"linkState",{"type":52,"value":242},{"type":46,"tag":61,"props":544,"children":546},{"className":545},[],[547],{"type":52,"value":548},"compatibility()",{"type":52,"value":550}," and keeps ",{"type":46,"tag":61,"props":552,"children":554},{"className":553},[],[555],{"type":52,"value":556},"addLinkStateListener",{"type":52,"value":558}," \u002F ",{"type":46,"tag":61,"props":560,"children":562},{"className":561},[],[563],{"type":52,"value":564},"addCompatibilityListener",{"type":52,"value":566}," tokens alive while rows are visible. If ",{"type":46,"tag":61,"props":568,"children":570},{"className":569},[],[571],{"type":52,"value":572},"compatibility() == .deviceUpdateRequired",{"type":52,"value":574},", surface a firmware update action through ",{"type":46,"tag":61,"props":576,"children":578},{"className":577},[],[579],{"type":52,"value":580},"Wearables.shared.openFirmwareUpdate()",{"type":52,"value":199},{"type":46,"tag":107,"props":583,"children":585},{"id":584},"attach-display-after-the-session-starts",[586],{"type":52,"value":587},"Attach Display after the session starts",{"type":46,"tag":55,"props":589,"children":590},{},[591,593,599,601,607,609,615,617,623],{"type":52,"value":592},"Create and start the ",{"type":46,"tag":61,"props":594,"children":596},{"className":595},[],[597],{"type":52,"value":598},"DeviceSession",{"type":52,"value":600},", wait for ",{"type":46,"tag":61,"props":602,"children":604},{"className":603},[],[605],{"type":52,"value":606},".started",{"type":52,"value":608},", then add and start ",{"type":46,"tag":61,"props":610,"children":612},{"className":611},[],[613],{"type":52,"value":614},"Display",{"type":52,"value":616},". Keep the state listener token alive for as long as you need updates, and observe ",{"type":46,"tag":61,"props":618,"children":620},{"className":619},[],[621],{"type":52,"value":622},"session.errorStream()",{"type":52,"value":624}," for async session failures.",{"type":46,"tag":134,"props":626,"children":628},{"className":136,"code":627,"language":138,"meta":139,"style":139},"import MWDATCore\nimport MWDATDisplay\n\n@MainActor\nfinal class DisplayController {\n  private var deviceSession: DeviceSession?\n  private var display: Display?\n  private var displayStateToken: AnyListenerToken?\n  private var sessionErrorTask: Task\u003CVoid, Never>?\n\n  func connect() async {\n    do {\n      let wearables = Wearables.shared\n      let selector = AutoDeviceSelector(\n        wearables: wearables,\n        filter: { $0.supportsDisplay() }\n      )\n\n      let session = try wearables.createSession(deviceSelector: selector)\n      deviceSession = session\n      sessionErrorTask = Task { [weak self] in\n        for await error in session.errorStream() {\n          await self?.showError(error.localizedDescription)\n        }\n      }\n\n      let sessionStarted = Task {\n        for await state in session.stateStream() {\n          if state == .started {\n            return\n          }\n        }\n      }\n      do {\n        try session.start()\n        await sessionStarted.value\n      } catch {\n        sessionStarted.cancel()\n        throw error\n      }\n\n      let capability = try session.addDisplay()\n      display = capability\n      displayStateToken = capability.statePublisher.listen { [weak self] state in\n        Task { @MainActor in\n          if state == .started {\n            self?.showStatusCard()\n          }\n        }\n      }\n\n      capability.start()\n    } catch DeviceSessionError.datAppOnTheGlassesUpdateRequired {\n      showDATGlassesAppUpdate()\n    } catch {\n      showError(error.localizedDescription)\n    }\n  }\n\n  func disconnect() async {\n    display?.onPlaybackEvent = nil\n    display?.stop()\n    deviceSession?.stop()\n    sessionErrorTask?.cancel()\n    sessionErrorTask = nil\n    displayStateToken = nil\n    display = nil\n    deviceSession = nil\n  }\n}\n",[629],{"type":46,"tag":61,"props":630,"children":631},{"__ignoreMap":139},[632,639,646,655,663,671,680,689,698,707,715,724,733,742,751,760,769,778,786,795,804,813,822,831,840,849,857,866,875,884,893,902,910,918,927,936,945,954,963,972,980,988,997,1006,1015,1024,1032,1041,1049,1057,1065,1073,1082,1091,1100,1109,1118,1127,1136,1144,1153,1162,1171,1180,1189,1198,1207,1216,1225,1233],{"type":46,"tag":145,"props":633,"children":634},{"class":147,"line":148},[635],{"type":46,"tag":145,"props":636,"children":637},{},[638],{"type":52,"value":154},{"type":46,"tag":145,"props":640,"children":641},{"class":147,"line":157},[642],{"type":46,"tag":145,"props":643,"children":644},{},[645],{"type":52,"value":163},{"type":46,"tag":145,"props":647,"children":648},{"class":147,"line":392},[649],{"type":46,"tag":145,"props":650,"children":652},{"emptyLinePlaceholder":651},true,[653],{"type":52,"value":654},"\n",{"type":46,"tag":145,"props":656,"children":657},{"class":147,"line":401},[658],{"type":46,"tag":145,"props":659,"children":660},{},[661],{"type":52,"value":662},"@MainActor\n",{"type":46,"tag":145,"props":664,"children":665},{"class":147,"line":410},[666],{"type":46,"tag":145,"props":667,"children":668},{},[669],{"type":52,"value":670},"final class DisplayController {\n",{"type":46,"tag":145,"props":672,"children":674},{"class":147,"line":673},6,[675],{"type":46,"tag":145,"props":676,"children":677},{},[678],{"type":52,"value":679},"  private var deviceSession: DeviceSession?\n",{"type":46,"tag":145,"props":681,"children":683},{"class":147,"line":682},7,[684],{"type":46,"tag":145,"props":685,"children":686},{},[687],{"type":52,"value":688},"  private var display: Display?\n",{"type":46,"tag":145,"props":690,"children":692},{"class":147,"line":691},8,[693],{"type":46,"tag":145,"props":694,"children":695},{},[696],{"type":52,"value":697},"  private var displayStateToken: AnyListenerToken?\n",{"type":46,"tag":145,"props":699,"children":701},{"class":147,"line":700},9,[702],{"type":46,"tag":145,"props":703,"children":704},{},[705],{"type":52,"value":706},"  private var sessionErrorTask: Task\u003CVoid, Never>?\n",{"type":46,"tag":145,"props":708,"children":710},{"class":147,"line":709},10,[711],{"type":46,"tag":145,"props":712,"children":713},{"emptyLinePlaceholder":651},[714],{"type":52,"value":654},{"type":46,"tag":145,"props":716,"children":718},{"class":147,"line":717},11,[719],{"type":46,"tag":145,"props":720,"children":721},{},[722],{"type":52,"value":723},"  func connect() async {\n",{"type":46,"tag":145,"props":725,"children":727},{"class":147,"line":726},12,[728],{"type":46,"tag":145,"props":729,"children":730},{},[731],{"type":52,"value":732},"    do {\n",{"type":46,"tag":145,"props":734,"children":736},{"class":147,"line":735},13,[737],{"type":46,"tag":145,"props":738,"children":739},{},[740],{"type":52,"value":741},"      let wearables = Wearables.shared\n",{"type":46,"tag":145,"props":743,"children":745},{"class":147,"line":744},14,[746],{"type":46,"tag":145,"props":747,"children":748},{},[749],{"type":52,"value":750},"      let selector = AutoDeviceSelector(\n",{"type":46,"tag":145,"props":752,"children":754},{"class":147,"line":753},15,[755],{"type":46,"tag":145,"props":756,"children":757},{},[758],{"type":52,"value":759},"        wearables: wearables,\n",{"type":46,"tag":145,"props":761,"children":763},{"class":147,"line":762},16,[764],{"type":46,"tag":145,"props":765,"children":766},{},[767],{"type":52,"value":768},"        filter: { $0.supportsDisplay() }\n",{"type":46,"tag":145,"props":770,"children":772},{"class":147,"line":771},17,[773],{"type":46,"tag":145,"props":774,"children":775},{},[776],{"type":52,"value":777},"      )\n",{"type":46,"tag":145,"props":779,"children":781},{"class":147,"line":780},18,[782],{"type":46,"tag":145,"props":783,"children":784},{"emptyLinePlaceholder":651},[785],{"type":52,"value":654},{"type":46,"tag":145,"props":787,"children":789},{"class":147,"line":788},19,[790],{"type":46,"tag":145,"props":791,"children":792},{},[793],{"type":52,"value":794},"      let session = try wearables.createSession(deviceSelector: selector)\n",{"type":46,"tag":145,"props":796,"children":798},{"class":147,"line":797},20,[799],{"type":46,"tag":145,"props":800,"children":801},{},[802],{"type":52,"value":803},"      deviceSession = session\n",{"type":46,"tag":145,"props":805,"children":807},{"class":147,"line":806},21,[808],{"type":46,"tag":145,"props":809,"children":810},{},[811],{"type":52,"value":812},"      sessionErrorTask = Task { [weak self] in\n",{"type":46,"tag":145,"props":814,"children":816},{"class":147,"line":815},22,[817],{"type":46,"tag":145,"props":818,"children":819},{},[820],{"type":52,"value":821},"        for await error in session.errorStream() {\n",{"type":46,"tag":145,"props":823,"children":825},{"class":147,"line":824},23,[826],{"type":46,"tag":145,"props":827,"children":828},{},[829],{"type":52,"value":830},"          await self?.showError(error.localizedDescription)\n",{"type":46,"tag":145,"props":832,"children":834},{"class":147,"line":833},24,[835],{"type":46,"tag":145,"props":836,"children":837},{},[838],{"type":52,"value":839},"        }\n",{"type":46,"tag":145,"props":841,"children":843},{"class":147,"line":842},25,[844],{"type":46,"tag":145,"props":845,"children":846},{},[847],{"type":52,"value":848},"      }\n",{"type":46,"tag":145,"props":850,"children":852},{"class":147,"line":851},26,[853],{"type":46,"tag":145,"props":854,"children":855},{"emptyLinePlaceholder":651},[856],{"type":52,"value":654},{"type":46,"tag":145,"props":858,"children":860},{"class":147,"line":859},27,[861],{"type":46,"tag":145,"props":862,"children":863},{},[864],{"type":52,"value":865},"      let sessionStarted = Task {\n",{"type":46,"tag":145,"props":867,"children":869},{"class":147,"line":868},28,[870],{"type":46,"tag":145,"props":871,"children":872},{},[873],{"type":52,"value":874},"        for await state in session.stateStream() {\n",{"type":46,"tag":145,"props":876,"children":878},{"class":147,"line":877},29,[879],{"type":46,"tag":145,"props":880,"children":881},{},[882],{"type":52,"value":883},"          if state == .started {\n",{"type":46,"tag":145,"props":885,"children":887},{"class":147,"line":886},30,[888],{"type":46,"tag":145,"props":889,"children":890},{},[891],{"type":52,"value":892},"            return\n",{"type":46,"tag":145,"props":894,"children":896},{"class":147,"line":895},31,[897],{"type":46,"tag":145,"props":898,"children":899},{},[900],{"type":52,"value":901},"          }\n",{"type":46,"tag":145,"props":903,"children":905},{"class":147,"line":904},32,[906],{"type":46,"tag":145,"props":907,"children":908},{},[909],{"type":52,"value":839},{"type":46,"tag":145,"props":911,"children":913},{"class":147,"line":912},33,[914],{"type":46,"tag":145,"props":915,"children":916},{},[917],{"type":52,"value":848},{"type":46,"tag":145,"props":919,"children":921},{"class":147,"line":920},34,[922],{"type":46,"tag":145,"props":923,"children":924},{},[925],{"type":52,"value":926},"      do {\n",{"type":46,"tag":145,"props":928,"children":930},{"class":147,"line":929},35,[931],{"type":46,"tag":145,"props":932,"children":933},{},[934],{"type":52,"value":935},"        try session.start()\n",{"type":46,"tag":145,"props":937,"children":939},{"class":147,"line":938},36,[940],{"type":46,"tag":145,"props":941,"children":942},{},[943],{"type":52,"value":944},"        await sessionStarted.value\n",{"type":46,"tag":145,"props":946,"children":948},{"class":147,"line":947},37,[949],{"type":46,"tag":145,"props":950,"children":951},{},[952],{"type":52,"value":953},"      } catch {\n",{"type":46,"tag":145,"props":955,"children":957},{"class":147,"line":956},38,[958],{"type":46,"tag":145,"props":959,"children":960},{},[961],{"type":52,"value":962},"        sessionStarted.cancel()\n",{"type":46,"tag":145,"props":964,"children":966},{"class":147,"line":965},39,[967],{"type":46,"tag":145,"props":968,"children":969},{},[970],{"type":52,"value":971},"        throw error\n",{"type":46,"tag":145,"props":973,"children":975},{"class":147,"line":974},40,[976],{"type":46,"tag":145,"props":977,"children":978},{},[979],{"type":52,"value":848},{"type":46,"tag":145,"props":981,"children":983},{"class":147,"line":982},41,[984],{"type":46,"tag":145,"props":985,"children":986},{"emptyLinePlaceholder":651},[987],{"type":52,"value":654},{"type":46,"tag":145,"props":989,"children":991},{"class":147,"line":990},42,[992],{"type":46,"tag":145,"props":993,"children":994},{},[995],{"type":52,"value":996},"      let capability = try session.addDisplay()\n",{"type":46,"tag":145,"props":998,"children":1000},{"class":147,"line":999},43,[1001],{"type":46,"tag":145,"props":1002,"children":1003},{},[1004],{"type":52,"value":1005},"      display = capability\n",{"type":46,"tag":145,"props":1007,"children":1009},{"class":147,"line":1008},44,[1010],{"type":46,"tag":145,"props":1011,"children":1012},{},[1013],{"type":52,"value":1014},"      displayStateToken = capability.statePublisher.listen { [weak self] state in\n",{"type":46,"tag":145,"props":1016,"children":1018},{"class":147,"line":1017},45,[1019],{"type":46,"tag":145,"props":1020,"children":1021},{},[1022],{"type":52,"value":1023},"        Task { @MainActor in\n",{"type":46,"tag":145,"props":1025,"children":1027},{"class":147,"line":1026},46,[1028],{"type":46,"tag":145,"props":1029,"children":1030},{},[1031],{"type":52,"value":883},{"type":46,"tag":145,"props":1033,"children":1035},{"class":147,"line":1034},47,[1036],{"type":46,"tag":145,"props":1037,"children":1038},{},[1039],{"type":52,"value":1040},"            self?.showStatusCard()\n",{"type":46,"tag":145,"props":1042,"children":1044},{"class":147,"line":1043},48,[1045],{"type":46,"tag":145,"props":1046,"children":1047},{},[1048],{"type":52,"value":901},{"type":46,"tag":145,"props":1050,"children":1052},{"class":147,"line":1051},49,[1053],{"type":46,"tag":145,"props":1054,"children":1055},{},[1056],{"type":52,"value":839},{"type":46,"tag":145,"props":1058,"children":1060},{"class":147,"line":1059},50,[1061],{"type":46,"tag":145,"props":1062,"children":1063},{},[1064],{"type":52,"value":848},{"type":46,"tag":145,"props":1066,"children":1068},{"class":147,"line":1067},51,[1069],{"type":46,"tag":145,"props":1070,"children":1071},{"emptyLinePlaceholder":651},[1072],{"type":52,"value":654},{"type":46,"tag":145,"props":1074,"children":1076},{"class":147,"line":1075},52,[1077],{"type":46,"tag":145,"props":1078,"children":1079},{},[1080],{"type":52,"value":1081},"      capability.start()\n",{"type":46,"tag":145,"props":1083,"children":1085},{"class":147,"line":1084},53,[1086],{"type":46,"tag":145,"props":1087,"children":1088},{},[1089],{"type":52,"value":1090},"    } catch DeviceSessionError.datAppOnTheGlassesUpdateRequired {\n",{"type":46,"tag":145,"props":1092,"children":1094},{"class":147,"line":1093},54,[1095],{"type":46,"tag":145,"props":1096,"children":1097},{},[1098],{"type":52,"value":1099},"      showDATGlassesAppUpdate()\n",{"type":46,"tag":145,"props":1101,"children":1103},{"class":147,"line":1102},55,[1104],{"type":46,"tag":145,"props":1105,"children":1106},{},[1107],{"type":52,"value":1108},"    } catch {\n",{"type":46,"tag":145,"props":1110,"children":1112},{"class":147,"line":1111},56,[1113],{"type":46,"tag":145,"props":1114,"children":1115},{},[1116],{"type":52,"value":1117},"      showError(error.localizedDescription)\n",{"type":46,"tag":145,"props":1119,"children":1121},{"class":147,"line":1120},57,[1122],{"type":46,"tag":145,"props":1123,"children":1124},{},[1125],{"type":52,"value":1126},"    }\n",{"type":46,"tag":145,"props":1128,"children":1130},{"class":147,"line":1129},58,[1131],{"type":46,"tag":145,"props":1132,"children":1133},{},[1134],{"type":52,"value":1135},"  }\n",{"type":46,"tag":145,"props":1137,"children":1139},{"class":147,"line":1138},59,[1140],{"type":46,"tag":145,"props":1141,"children":1142},{"emptyLinePlaceholder":651},[1143],{"type":52,"value":654},{"type":46,"tag":145,"props":1145,"children":1147},{"class":147,"line":1146},60,[1148],{"type":46,"tag":145,"props":1149,"children":1150},{},[1151],{"type":52,"value":1152},"  func disconnect() async {\n",{"type":46,"tag":145,"props":1154,"children":1156},{"class":147,"line":1155},61,[1157],{"type":46,"tag":145,"props":1158,"children":1159},{},[1160],{"type":52,"value":1161},"    display?.onPlaybackEvent = nil\n",{"type":46,"tag":145,"props":1163,"children":1165},{"class":147,"line":1164},62,[1166],{"type":46,"tag":145,"props":1167,"children":1168},{},[1169],{"type":52,"value":1170},"    display?.stop()\n",{"type":46,"tag":145,"props":1172,"children":1174},{"class":147,"line":1173},63,[1175],{"type":46,"tag":145,"props":1176,"children":1177},{},[1178],{"type":52,"value":1179},"    deviceSession?.stop()\n",{"type":46,"tag":145,"props":1181,"children":1183},{"class":147,"line":1182},64,[1184],{"type":46,"tag":145,"props":1185,"children":1186},{},[1187],{"type":52,"value":1188},"    sessionErrorTask?.cancel()\n",{"type":46,"tag":145,"props":1190,"children":1192},{"class":147,"line":1191},65,[1193],{"type":46,"tag":145,"props":1194,"children":1195},{},[1196],{"type":52,"value":1197},"    sessionErrorTask = nil\n",{"type":46,"tag":145,"props":1199,"children":1201},{"class":147,"line":1200},66,[1202],{"type":46,"tag":145,"props":1203,"children":1204},{},[1205],{"type":52,"value":1206},"    displayStateToken = nil\n",{"type":46,"tag":145,"props":1208,"children":1210},{"class":147,"line":1209},67,[1211],{"type":46,"tag":145,"props":1212,"children":1213},{},[1214],{"type":52,"value":1215},"    display = nil\n",{"type":46,"tag":145,"props":1217,"children":1219},{"class":147,"line":1218},68,[1220],{"type":46,"tag":145,"props":1221,"children":1222},{},[1223],{"type":52,"value":1224},"    deviceSession = nil\n",{"type":46,"tag":145,"props":1226,"children":1228},{"class":147,"line":1227},69,[1229],{"type":46,"tag":145,"props":1230,"children":1231},{},[1232],{"type":52,"value":1135},{"type":46,"tag":145,"props":1234,"children":1236},{"class":147,"line":1235},70,[1237],{"type":46,"tag":145,"props":1238,"children":1239},{},[1240],{"type":52,"value":1241},"}\n",{"type":46,"tag":55,"props":1243,"children":1244},{},[1245,1247,1253,1255,1261,1263,1269],{"type":52,"value":1246},"For user-triggered content, match the sample's pending-action pattern: if the user taps \"Try it\" before Display is connected, store the send as a pending async action, attach to Display, and run the action when ",{"type":46,"tag":61,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":52,"value":1252},"DisplayState.started",{"type":52,"value":1254}," arrives. Reset the display session when registration changes to ",{"type":46,"tag":61,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":52,"value":1260},".available",{"type":52,"value":1262}," or ",{"type":46,"tag":61,"props":1264,"children":1266},{"className":1265},[],[1267],{"type":52,"value":1268},".unavailable",{"type":52,"value":199},{"type":46,"tag":107,"props":1271,"children":1273},{"id":1272},"send-display-ui",[1274],{"type":52,"value":1275},"Send display UI",{"type":46,"tag":55,"props":1277,"children":1278},{},[1279,1281,1287,1289,1295,1297,1303,1305,1311,1313,1319,1320,1326,1327,1333,1335,1341,1343,1348],{"type":52,"value":1280},"Build exactly one root ",{"type":46,"tag":61,"props":1282,"children":1284},{"className":1283},[],[1285],{"type":52,"value":1286},"DisplayableView",{"type":52,"value":1288}," per ",{"type":46,"tag":61,"props":1290,"children":1292},{"className":1291},[],[1293],{"type":52,"value":1294},"send(_:)",{"type":52,"value":1296}," call. Each send replaces the previous content on the glasses and replaces the active tap handlers. Use a root ",{"type":46,"tag":61,"props":1298,"children":1300},{"className":1299},[],[1301],{"type":52,"value":1302},"FlexBox",{"type":52,"value":1304}," for UI, or a root ",{"type":46,"tag":61,"props":1306,"children":1308},{"className":1307},[],[1309],{"type":52,"value":1310},"VideoPlayer",{"type":52,"value":1312}," for video. Do not send ",{"type":46,"tag":61,"props":1314,"children":1316},{"className":1315},[],[1317],{"type":52,"value":1318},"Text",{"type":52,"value":220},{"type":46,"tag":61,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":52,"value":1325},"Button",{"type":52,"value":220},{"type":46,"tag":61,"props":1328,"children":1330},{"className":1329},[],[1331],{"type":52,"value":1332},"Image",{"type":52,"value":1334},", or ",{"type":46,"tag":61,"props":1336,"children":1338},{"className":1337},[],[1339],{"type":52,"value":1340},"Icon",{"type":52,"value":1342}," as the root; place them inside a ",{"type":46,"tag":61,"props":1344,"children":1346},{"className":1345},[],[1347],{"type":52,"value":1302},{"type":52,"value":199},{"type":46,"tag":55,"props":1350,"children":1351},{},[1352,1354,1359,1360,1365,1366,1371,1373,1378,1380,1386,1387,1393,1394,1400],{"type":52,"value":1353},"If a file also imports SwiftUI, Display DSL names such as ",{"type":46,"tag":61,"props":1355,"children":1357},{"className":1356},[],[1358],{"type":52,"value":1318},{"type":52,"value":220},{"type":46,"tag":61,"props":1361,"children":1363},{"className":1362},[],[1364],{"type":52,"value":1325},{"type":52,"value":242},{"type":46,"tag":61,"props":1367,"children":1369},{"className":1368},[],[1370],{"type":52,"value":1332},{"type":52,"value":1372}," can be ambiguous. Prefer keeping Display builders in files that import ",{"type":46,"tag":61,"props":1374,"children":1376},{"className":1375},[],[1377],{"type":52,"value":66},{"type":52,"value":1379}," without SwiftUI, or qualify the symbols as ",{"type":46,"tag":61,"props":1381,"children":1383},{"className":1382},[],[1384],{"type":52,"value":1385},"MWDATDisplay.Text",{"type":52,"value":220},{"type":46,"tag":61,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":52,"value":1392},"MWDATDisplay.Button",{"type":52,"value":242},{"type":46,"tag":61,"props":1395,"children":1397},{"className":1396},[],[1398],{"type":52,"value":1399},"MWDATDisplay.Image",{"type":52,"value":199},{"type":46,"tag":134,"props":1402,"children":1404},{"className":136,"code":1403,"language":138,"meta":139,"style":139},"func showStatusCard() {\n  Task {\n    do {\n      try await display?.send(\n        FlexBox(direction: .column, spacing: 12) {\n          Text(\"Bike ride\", style: .heading)\n          Text(\"Turn right in 200 ft\", style: .body, color: .secondary)\n          Button(\n            label: \"Done\",\n            style: .primary,\n            iconName: .checkmark,\n            onClick: { print(\"Done tapped\") }\n          )\n        }\n        .padding(24)\n        .background(.card)\n        .onTap { print(\"Card tapped\") }\n      )\n    } catch {\n      showError((error as? DisplayError)?.description ?? error.localizedDescription)\n    }\n  }\n}\n",[1405],{"type":46,"tag":61,"props":1406,"children":1407},{"__ignoreMap":139},[1408,1416,1424,1431,1439,1447,1455,1463,1471,1479,1487,1495,1503,1511,1518,1526,1534,1542,1549,1556,1564,1571,1578],{"type":46,"tag":145,"props":1409,"children":1410},{"class":147,"line":148},[1411],{"type":46,"tag":145,"props":1412,"children":1413},{},[1414],{"type":52,"value":1415},"func showStatusCard() {\n",{"type":46,"tag":145,"props":1417,"children":1418},{"class":147,"line":157},[1419],{"type":46,"tag":145,"props":1420,"children":1421},{},[1422],{"type":52,"value":1423},"  Task {\n",{"type":46,"tag":145,"props":1425,"children":1426},{"class":147,"line":392},[1427],{"type":46,"tag":145,"props":1428,"children":1429},{},[1430],{"type":52,"value":732},{"type":46,"tag":145,"props":1432,"children":1433},{"class":147,"line":401},[1434],{"type":46,"tag":145,"props":1435,"children":1436},{},[1437],{"type":52,"value":1438},"      try await display?.send(\n",{"type":46,"tag":145,"props":1440,"children":1441},{"class":147,"line":410},[1442],{"type":46,"tag":145,"props":1443,"children":1444},{},[1445],{"type":52,"value":1446},"        FlexBox(direction: .column, spacing: 12) {\n",{"type":46,"tag":145,"props":1448,"children":1449},{"class":147,"line":673},[1450],{"type":46,"tag":145,"props":1451,"children":1452},{},[1453],{"type":52,"value":1454},"          Text(\"Bike ride\", style: .heading)\n",{"type":46,"tag":145,"props":1456,"children":1457},{"class":147,"line":682},[1458],{"type":46,"tag":145,"props":1459,"children":1460},{},[1461],{"type":52,"value":1462},"          Text(\"Turn right in 200 ft\", style: .body, color: .secondary)\n",{"type":46,"tag":145,"props":1464,"children":1465},{"class":147,"line":691},[1466],{"type":46,"tag":145,"props":1467,"children":1468},{},[1469],{"type":52,"value":1470},"          Button(\n",{"type":46,"tag":145,"props":1472,"children":1473},{"class":147,"line":700},[1474],{"type":46,"tag":145,"props":1475,"children":1476},{},[1477],{"type":52,"value":1478},"            label: \"Done\",\n",{"type":46,"tag":145,"props":1480,"children":1481},{"class":147,"line":709},[1482],{"type":46,"tag":145,"props":1483,"children":1484},{},[1485],{"type":52,"value":1486},"            style: .primary,\n",{"type":46,"tag":145,"props":1488,"children":1489},{"class":147,"line":717},[1490],{"type":46,"tag":145,"props":1491,"children":1492},{},[1493],{"type":52,"value":1494},"            iconName: .checkmark,\n",{"type":46,"tag":145,"props":1496,"children":1497},{"class":147,"line":726},[1498],{"type":46,"tag":145,"props":1499,"children":1500},{},[1501],{"type":52,"value":1502},"            onClick: { print(\"Done tapped\") }\n",{"type":46,"tag":145,"props":1504,"children":1505},{"class":147,"line":735},[1506],{"type":46,"tag":145,"props":1507,"children":1508},{},[1509],{"type":52,"value":1510},"          )\n",{"type":46,"tag":145,"props":1512,"children":1513},{"class":147,"line":744},[1514],{"type":46,"tag":145,"props":1515,"children":1516},{},[1517],{"type":52,"value":839},{"type":46,"tag":145,"props":1519,"children":1520},{"class":147,"line":753},[1521],{"type":46,"tag":145,"props":1522,"children":1523},{},[1524],{"type":52,"value":1525},"        .padding(24)\n",{"type":46,"tag":145,"props":1527,"children":1528},{"class":147,"line":762},[1529],{"type":46,"tag":145,"props":1530,"children":1531},{},[1532],{"type":52,"value":1533},"        .background(.card)\n",{"type":46,"tag":145,"props":1535,"children":1536},{"class":147,"line":771},[1537],{"type":46,"tag":145,"props":1538,"children":1539},{},[1540],{"type":52,"value":1541},"        .onTap { print(\"Card tapped\") }\n",{"type":46,"tag":145,"props":1543,"children":1544},{"class":147,"line":780},[1545],{"type":46,"tag":145,"props":1546,"children":1547},{},[1548],{"type":52,"value":777},{"type":46,"tag":145,"props":1550,"children":1551},{"class":147,"line":788},[1552],{"type":46,"tag":145,"props":1553,"children":1554},{},[1555],{"type":52,"value":1108},{"type":46,"tag":145,"props":1557,"children":1558},{"class":147,"line":797},[1559],{"type":46,"tag":145,"props":1560,"children":1561},{},[1562],{"type":52,"value":1563},"      showError((error as? DisplayError)?.description ?? error.localizedDescription)\n",{"type":46,"tag":145,"props":1565,"children":1566},{"class":147,"line":806},[1567],{"type":46,"tag":145,"props":1568,"children":1569},{},[1570],{"type":52,"value":1126},{"type":46,"tag":145,"props":1572,"children":1573},{"class":147,"line":815},[1574],{"type":46,"tag":145,"props":1575,"children":1576},{},[1577],{"type":52,"value":1135},{"type":46,"tag":145,"props":1579,"children":1580},{"class":147,"line":824},[1581],{"type":46,"tag":145,"props":1582,"children":1583},{},[1584],{"type":52,"value":1241},{"type":46,"tag":107,"props":1586,"children":1588},{"id":1587},"use-images-and-built-in-icons",[1589],{"type":52,"value":1590},"Use images and built-in icons",{"type":46,"tag":55,"props":1592,"children":1593},{},[1594,1596,1602],{"type":52,"value":1595},"Use HTTPS image URLs for image content, and use the ",{"type":46,"tag":61,"props":1597,"children":1599},{"className":1598},[],[1600],{"type":52,"value":1601},"IconName",{"type":52,"value":1603}," enum for built-in icons. Do not invent raw icon strings.",{"type":46,"tag":134,"props":1605,"children":1607},{"className":136,"code":1606,"language":138,"meta":139,"style":139},"try await display.send(\n  FlexBox(direction: .row, spacing: 8, crossAlignment: .center) {\n    Image(\n      uri: \"https:\u002F\u002Fexample.com\u002Fthumbnail.png\",\n      sizePreset: .fill,\n      cornerRadius: .medium\n    )\n    Icon(name: .gear, style: .filled)\n    Text(\"Device settings\", style: .body)\n  }\n  .padding(24)\n)\n",[1608],{"type":46,"tag":61,"props":1609,"children":1610},{"__ignoreMap":139},[1611,1619,1627,1635,1643,1651,1659,1667,1675,1683,1690,1698],{"type":46,"tag":145,"props":1612,"children":1613},{"class":147,"line":148},[1614],{"type":46,"tag":145,"props":1615,"children":1616},{},[1617],{"type":52,"value":1618},"try await display.send(\n",{"type":46,"tag":145,"props":1620,"children":1621},{"class":147,"line":157},[1622],{"type":46,"tag":145,"props":1623,"children":1624},{},[1625],{"type":52,"value":1626},"  FlexBox(direction: .row, spacing: 8, crossAlignment: .center) {\n",{"type":46,"tag":145,"props":1628,"children":1629},{"class":147,"line":392},[1630],{"type":46,"tag":145,"props":1631,"children":1632},{},[1633],{"type":52,"value":1634},"    Image(\n",{"type":46,"tag":145,"props":1636,"children":1637},{"class":147,"line":401},[1638],{"type":46,"tag":145,"props":1639,"children":1640},{},[1641],{"type":52,"value":1642},"      uri: \"https:\u002F\u002Fexample.com\u002Fthumbnail.png\",\n",{"type":46,"tag":145,"props":1644,"children":1645},{"class":147,"line":410},[1646],{"type":46,"tag":145,"props":1647,"children":1648},{},[1649],{"type":52,"value":1650},"      sizePreset: .fill,\n",{"type":46,"tag":145,"props":1652,"children":1653},{"class":147,"line":673},[1654],{"type":46,"tag":145,"props":1655,"children":1656},{},[1657],{"type":52,"value":1658},"      cornerRadius: .medium\n",{"type":46,"tag":145,"props":1660,"children":1661},{"class":147,"line":682},[1662],{"type":46,"tag":145,"props":1663,"children":1664},{},[1665],{"type":52,"value":1666},"    )\n",{"type":46,"tag":145,"props":1668,"children":1669},{"class":147,"line":691},[1670],{"type":46,"tag":145,"props":1671,"children":1672},{},[1673],{"type":52,"value":1674},"    Icon(name: .gear, style: .filled)\n",{"type":46,"tag":145,"props":1676,"children":1677},{"class":147,"line":700},[1678],{"type":46,"tag":145,"props":1679,"children":1680},{},[1681],{"type":52,"value":1682},"    Text(\"Device settings\", style: .body)\n",{"type":46,"tag":145,"props":1684,"children":1685},{"class":147,"line":709},[1686],{"type":46,"tag":145,"props":1687,"children":1688},{},[1689],{"type":52,"value":1135},{"type":46,"tag":145,"props":1691,"children":1692},{"class":147,"line":717},[1693],{"type":46,"tag":145,"props":1694,"children":1695},{},[1696],{"type":52,"value":1697},"  .padding(24)\n",{"type":46,"tag":145,"props":1699,"children":1700},{"class":147,"line":726},[1701],{"type":46,"tag":145,"props":1702,"children":1703},{},[1704],{"type":52,"value":416},{"type":46,"tag":107,"props":1706,"children":1708},{"id":1707},"send-video",[1709],{"type":52,"value":1710},"Send video",{"type":46,"tag":55,"props":1712,"children":1713},{},[1714,1716,1721,1723,1729,1731,1737,1739,1745,1747,1753,1755,1761],{"type":52,"value":1715},"For URL-based video, send a root ",{"type":46,"tag":61,"props":1717,"children":1719},{"className":1718},[],[1720],{"type":52,"value":1310},{"type":52,"value":1722},". Use ",{"type":46,"tag":61,"props":1724,"children":1726},{"className":1725},[],[1727],{"type":52,"value":1728},"VideoPlayer(onError:)",{"type":52,"value":1730}," for video-specific errors, and use ",{"type":46,"tag":61,"props":1732,"children":1734},{"className":1733},[],[1735],{"type":52,"value":1736},"display.onPlaybackEvent",{"type":52,"value":1738}," for playback events. Set ",{"type":46,"tag":61,"props":1740,"children":1742},{"className":1741},[],[1743],{"type":52,"value":1744},"onPlaybackEvent",{"type":52,"value":1746}," before sending the video, clear it after terminal events if the flow is complete, and call ",{"type":46,"tag":61,"props":1748,"children":1750},{"className":1749},[],[1751],{"type":52,"value":1752},"sendVideoStop()",{"type":52,"value":1754}," if the user exits playback early. Blank or non-HTTP(S) URLs throw ",{"type":46,"tag":61,"props":1756,"children":1758},{"className":1757},[],[1759],{"type":52,"value":1760},"DisplayError.invalidVideoURL",{"type":52,"value":199},{"type":46,"tag":134,"props":1763,"children":1765},{"className":136,"code":1764,"language":138,"meta":139,"style":139},"display.onPlaybackEvent = { event in\n  if event.type == .ended || event.type == .stopped {\n    Task { @MainActor in\n      display.onPlaybackEvent = nil\n      showStatusCard()\n    }\n  }\n}\n\ntry await display.send(\n  VideoPlayer(\n    provider: .uri(\"https:\u002F\u002Fexample.com\u002Ftutorial.mp4\"),\n    codec: .mp4,\n    onError: { error in\n      Task { @MainActor in\n        showError(error.localizedDescription)\n      }\n    }\n  )\n)\n",[1766],{"type":46,"tag":61,"props":1767,"children":1768},{"__ignoreMap":139},[1769,1777,1785,1793,1801,1809,1816,1823,1830,1837,1844,1852,1860,1868,1876,1884,1892,1899,1906,1914],{"type":46,"tag":145,"props":1770,"children":1771},{"class":147,"line":148},[1772],{"type":46,"tag":145,"props":1773,"children":1774},{},[1775],{"type":52,"value":1776},"display.onPlaybackEvent = { event in\n",{"type":46,"tag":145,"props":1778,"children":1779},{"class":147,"line":157},[1780],{"type":46,"tag":145,"props":1781,"children":1782},{},[1783],{"type":52,"value":1784},"  if event.type == .ended || event.type == .stopped {\n",{"type":46,"tag":145,"props":1786,"children":1787},{"class":147,"line":392},[1788],{"type":46,"tag":145,"props":1789,"children":1790},{},[1791],{"type":52,"value":1792},"    Task { @MainActor in\n",{"type":46,"tag":145,"props":1794,"children":1795},{"class":147,"line":401},[1796],{"type":46,"tag":145,"props":1797,"children":1798},{},[1799],{"type":52,"value":1800},"      display.onPlaybackEvent = nil\n",{"type":46,"tag":145,"props":1802,"children":1803},{"class":147,"line":410},[1804],{"type":46,"tag":145,"props":1805,"children":1806},{},[1807],{"type":52,"value":1808},"      showStatusCard()\n",{"type":46,"tag":145,"props":1810,"children":1811},{"class":147,"line":673},[1812],{"type":46,"tag":145,"props":1813,"children":1814},{},[1815],{"type":52,"value":1126},{"type":46,"tag":145,"props":1817,"children":1818},{"class":147,"line":682},[1819],{"type":46,"tag":145,"props":1820,"children":1821},{},[1822],{"type":52,"value":1135},{"type":46,"tag":145,"props":1824,"children":1825},{"class":147,"line":691},[1826],{"type":46,"tag":145,"props":1827,"children":1828},{},[1829],{"type":52,"value":1241},{"type":46,"tag":145,"props":1831,"children":1832},{"class":147,"line":700},[1833],{"type":46,"tag":145,"props":1834,"children":1835},{"emptyLinePlaceholder":651},[1836],{"type":52,"value":654},{"type":46,"tag":145,"props":1838,"children":1839},{"class":147,"line":709},[1840],{"type":46,"tag":145,"props":1841,"children":1842},{},[1843],{"type":52,"value":1618},{"type":46,"tag":145,"props":1845,"children":1846},{"class":147,"line":717},[1847],{"type":46,"tag":145,"props":1848,"children":1849},{},[1850],{"type":52,"value":1851},"  VideoPlayer(\n",{"type":46,"tag":145,"props":1853,"children":1854},{"class":147,"line":726},[1855],{"type":46,"tag":145,"props":1856,"children":1857},{},[1858],{"type":52,"value":1859},"    provider: .uri(\"https:\u002F\u002Fexample.com\u002Ftutorial.mp4\"),\n",{"type":46,"tag":145,"props":1861,"children":1862},{"class":147,"line":735},[1863],{"type":46,"tag":145,"props":1864,"children":1865},{},[1866],{"type":52,"value":1867},"    codec: .mp4,\n",{"type":46,"tag":145,"props":1869,"children":1870},{"class":147,"line":744},[1871],{"type":46,"tag":145,"props":1872,"children":1873},{},[1874],{"type":52,"value":1875},"    onError: { error in\n",{"type":46,"tag":145,"props":1877,"children":1878},{"class":147,"line":753},[1879],{"type":46,"tag":145,"props":1880,"children":1881},{},[1882],{"type":52,"value":1883},"      Task { @MainActor in\n",{"type":46,"tag":145,"props":1885,"children":1886},{"class":147,"line":762},[1887],{"type":46,"tag":145,"props":1888,"children":1889},{},[1890],{"type":52,"value":1891},"        showError(error.localizedDescription)\n",{"type":46,"tag":145,"props":1893,"children":1894},{"class":147,"line":771},[1895],{"type":46,"tag":145,"props":1896,"children":1897},{},[1898],{"type":52,"value":848},{"type":46,"tag":145,"props":1900,"children":1901},{"class":147,"line":780},[1902],{"type":46,"tag":145,"props":1903,"children":1904},{},[1905],{"type":52,"value":1126},{"type":46,"tag":145,"props":1907,"children":1908},{"class":147,"line":788},[1909],{"type":46,"tag":145,"props":1910,"children":1911},{},[1912],{"type":52,"value":1913},"  )\n",{"type":46,"tag":145,"props":1915,"children":1916},{"class":147,"line":797},[1917],{"type":46,"tag":145,"props":1918,"children":1919},{},[1920],{"type":52,"value":416},{"type":46,"tag":107,"props":1922,"children":1924},{"id":1923},"display-rules",[1925],{"type":52,"value":1926},"Display rules",{"type":46,"tag":176,"props":1928,"children":1929},{},[1930,1942,1955,1981,2001,2028,2040,2045,2056,2086,2105,2222,2234],{"type":46,"tag":180,"props":1931,"children":1932},{},[1933,1935,1940],{"type":52,"value":1934},"Call ",{"type":46,"tag":61,"props":1936,"children":1938},{"className":1937},[],[1939],{"type":52,"value":95},{"type":52,"value":1941}," at app launch and complete registration before creating the session.",{"type":46,"tag":180,"props":1943,"children":1944},{},[1945,1947,1953],{"type":52,"value":1946},"Enable ",{"type":46,"tag":61,"props":1948,"children":1950},{"className":1949},[],[1951],{"type":52,"value":1952},"MWDAT.DAMEnabled",{"type":52,"value":1954}," for Display sessions, and include the DisplayAccess sample's link-lease Info.plist keys when building a full Display app.",{"type":46,"tag":180,"props":1956,"children":1957},{},[1958,1960,1965,1967,1972,1974,1980],{"type":52,"value":1959},"Wait for the ",{"type":46,"tag":61,"props":1961,"children":1963},{"className":1962},[],[1964],{"type":52,"value":598},{"type":52,"value":1966}," to reach ",{"type":46,"tag":61,"props":1968,"children":1970},{"className":1969},[],[1971],{"type":52,"value":606},{"type":52,"value":1973}," before calling ",{"type":46,"tag":61,"props":1975,"children":1977},{"className":1976},[],[1978],{"type":52,"value":1979},"addDisplay()",{"type":52,"value":199},{"type":46,"tag":180,"props":1982,"children":1983},{},[1984,1986,1992,1994,2000],{"type":52,"value":1985},"Handle ",{"type":46,"tag":61,"props":1987,"children":1989},{"className":1988},[],[1990],{"type":52,"value":1991},"DeviceSessionError.datAppOnTheGlassesUpdateRequired",{"type":52,"value":1993}," separately and offer ",{"type":46,"tag":61,"props":1995,"children":1997},{"className":1996},[],[1998],{"type":52,"value":1999},"Wearables.shared.openDATGlassesAppUpdate()",{"type":52,"value":199},{"type":46,"tag":180,"props":2002,"children":2003},{},[2004,2005,2011,2013,2018,2020,2026],{"type":52,"value":1934},{"type":46,"tag":61,"props":2006,"children":2008},{"className":2007},[],[2009],{"type":52,"value":2010},"display.start()",{"type":52,"value":2012},", then wait for ",{"type":46,"tag":61,"props":2014,"children":2016},{"className":2015},[],[2017],{"type":52,"value":1252},{"type":52,"value":2019}," through ",{"type":46,"tag":61,"props":2021,"children":2023},{"className":2022},[],[2024],{"type":52,"value":2025},"statePublisher",{"type":52,"value":2027}," before sending user-triggered content.",{"type":46,"tag":180,"props":2029,"children":2030},{},[2031,2033,2038],{"type":52,"value":2032},"Observe ",{"type":46,"tag":61,"props":2034,"children":2036},{"className":2035},[],[2037],{"type":52,"value":622},{"type":52,"value":2039}," so async session failures are surfaced.",{"type":46,"tag":180,"props":2041,"children":2042},{},[2043],{"type":52,"value":2044},"Keep listener tokens alive; dropping a token stops that listener.",{"type":46,"tag":180,"props":2046,"children":2047},{},[2048,2050,2055],{"type":52,"value":2049},"Use the getting-started setup for Info.plist URL schemes and route app-open URLs to ",{"type":46,"tag":61,"props":2051,"children":2053},{"className":2052},[],[2054],{"type":52,"value":103},{"type":52,"value":199},{"type":46,"tag":180,"props":2057,"children":2058},{},[2059,2060,2065,2066,2072,2073,2078,2079,2084],{"type":52,"value":59},{"type":46,"tag":61,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":52,"value":527},{"type":52,"value":220},{"type":46,"tag":61,"props":2067,"children":2069},{"className":2068},[],[2070],{"type":52,"value":2071},"deviceType()",{"type":52,"value":220},{"type":46,"tag":61,"props":2074,"children":2076},{"className":2075},[],[2077],{"type":52,"value":541},{"type":52,"value":242},{"type":46,"tag":61,"props":2080,"children":2082},{"className":2081},[],[2083],{"type":52,"value":548},{"type":52,"value":2085}," for device rows; keep link\u002Fcompatibility listener tokens until the row is gone.",{"type":46,"tag":180,"props":2087,"children":2088},{},[2089,2090,2096,2097,2103],{"type":52,"value":59},{"type":46,"tag":61,"props":2091,"children":2093},{"className":2092},[],[2094],{"type":52,"value":2095},"FlexBox.onTap",{"type":52,"value":81},{"type":46,"tag":61,"props":2098,"children":2100},{"className":2099},[],[2101],{"type":52,"value":2102},"Button(label:onClick:)",{"type":52,"value":2104}," for interactions. The callbacks belong to the most recent sent view.",{"type":46,"tag":180,"props":2106,"children":2107},{},[2108,2110,2115,2116,2121,2122,2127,2128,2133,2134,2139,2140,2145,2146,2151,2152,2158,2159,2165,2166,2172,2173,2179,2180,2186,2187,2193,2194,2200,2201,2207,2208,2214,2215,2221],{"type":52,"value":2109},"Use only public Display DSL names: ",{"type":46,"tag":61,"props":2111,"children":2113},{"className":2112},[],[2114],{"type":52,"value":1302},{"type":52,"value":220},{"type":46,"tag":61,"props":2117,"children":2119},{"className":2118},[],[2120],{"type":52,"value":1318},{"type":52,"value":220},{"type":46,"tag":61,"props":2123,"children":2125},{"className":2124},[],[2126],{"type":52,"value":1325},{"type":52,"value":220},{"type":46,"tag":61,"props":2129,"children":2131},{"className":2130},[],[2132],{"type":52,"value":1332},{"type":52,"value":220},{"type":46,"tag":61,"props":2135,"children":2137},{"className":2136},[],[2138],{"type":52,"value":1340},{"type":52,"value":220},{"type":46,"tag":61,"props":2141,"children":2143},{"className":2142},[],[2144],{"type":52,"value":1310},{"type":52,"value":220},{"type":46,"tag":61,"props":2147,"children":2149},{"className":2148},[],[2150],{"type":52,"value":1601},{"type":52,"value":220},{"type":46,"tag":61,"props":2153,"children":2155},{"className":2154},[],[2156],{"type":52,"value":2157},"TextStyle",{"type":52,"value":220},{"type":46,"tag":61,"props":2160,"children":2162},{"className":2161},[],[2163],{"type":52,"value":2164},"TextColor",{"type":52,"value":220},{"type":46,"tag":61,"props":2167,"children":2169},{"className":2168},[],[2170],{"type":52,"value":2171},"ButtonStyle",{"type":52,"value":220},{"type":46,"tag":61,"props":2174,"children":2176},{"className":2175},[],[2177],{"type":52,"value":2178},"ImageSize",{"type":52,"value":220},{"type":46,"tag":61,"props":2181,"children":2183},{"className":2182},[],[2184],{"type":52,"value":2185},"CornerRadius",{"type":52,"value":220},{"type":46,"tag":61,"props":2188,"children":2190},{"className":2189},[],[2191],{"type":52,"value":2192},"Direction",{"type":52,"value":220},{"type":46,"tag":61,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":52,"value":2199},"Alignment",{"type":52,"value":220},{"type":46,"tag":61,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":52,"value":2206},"Background",{"type":52,"value":220},{"type":46,"tag":61,"props":2209,"children":2211},{"className":2210},[],[2212],{"type":52,"value":2213},"Edge",{"type":52,"value":242},{"type":46,"tag":61,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":52,"value":2220},"EdgeInsets",{"type":52,"value":199},{"type":46,"tag":180,"props":2223,"children":2224},{},[2225,2227,2232],{"type":52,"value":2226},"Clear ",{"type":46,"tag":61,"props":2228,"children":2230},{"className":2229},[],[2231],{"type":52,"value":1736},{"type":52,"value":2233}," when the video flow is finished if you no longer need playback callbacks.",{"type":46,"tag":180,"props":2235,"children":2236},{},[2237,2239,2244],{"type":52,"value":2238},"Stop Display before stopping the parent ",{"type":46,"tag":61,"props":2240,"children":2242},{"className":2241},[],[2243],{"type":52,"value":598},{"type":52,"value":2245}," when the display experience ends.",{"type":46,"tag":107,"props":2247,"children":2249},{"id":2248},"sample-app",[2250],{"type":52,"value":2251},"Sample app",{"type":46,"tag":55,"props":2253,"children":2254},{},[2255],{"type":52,"value":2256},"Use the Display Access sample app for a complete flow: registration, device selection, display attachment, interactive content, and video.",{"type":46,"tag":107,"props":2258,"children":2260},{"id":2259},"links",[2261],{"type":52,"value":2262},"Links",{"type":46,"tag":176,"props":2264,"children":2265},{},[2266,2278],{"type":46,"tag":180,"props":2267,"children":2268},{},[2269],{"type":46,"tag":2270,"props":2271,"children":2275},"a",{"href":2272,"rel":2273},"https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Freference\u002Fios_swift\u002Fdat\u002F0.8",[2274],"nofollow",[2276],{"type":52,"value":2277},"iOS API reference",{"type":46,"tag":180,"props":2279,"children":2280},{},[2281],{"type":46,"tag":2270,"props":2282,"children":2285},{"href":2283,"rel":2284},"https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Fdevelop\u002F",[2274],[2286],{"type":52,"value":2287},"Developer documentation",{"type":46,"tag":2289,"props":2290,"children":2291},"style",{},[2292],{"type":52,"value":2293},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2295,"total":700},[2296,2313,2329,2342,2350,2362,2377],{"slug":2297,"name":2297,"fn":2298,"description":2299,"org":2300,"tags":2301,"stars":29,"repoUrl":30,"updatedAt":2312},"camera-streaming","configure camera streaming and photo capture","Stream, video frames, photo capture, resolution\u002Fframe rate configuration",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2302,2305,2308,2311],{"name":2303,"slug":2304,"type":16},"Camera","camera",{"name":2306,"slug":2307,"type":16},"Hardware","hardware",{"name":2309,"slug":2310,"type":16},"iOS","ios",{"name":21,"slug":22,"type":16},"2026-05-15T06:14:43.555881",{"slug":2314,"name":2314,"fn":2315,"description":2316,"org":2317,"tags":2318,"stars":29,"repoUrl":30,"updatedAt":2328},"dat-conventions","develop iOS applications with DAT SDK","Swift patterns, async\u002Fawait, naming conventions, key types for DAT SDK iOS development",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2319,2320,2323,2326],{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},"Mobile","mobile",{"name":2324,"slug":2325,"type":16},"SDK","sdk",{"name":2327,"slug":138,"type":16},"Swift","2026-05-15T06:14:42.334435",{"slug":2330,"name":2330,"fn":2331,"description":2332,"org":2333,"tags":2334,"stars":29,"repoUrl":30,"updatedAt":2341},"debugging","debug wearable device software","Common issues, Developer Mode, version compatibility, state machine diagnosis",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2335,2337,2340],{"name":2336,"slug":2330,"type":16},"Debugging",{"name":2338,"slug":2339,"type":16},"Engineering","engineering",{"name":2309,"slug":2310,"type":16},"2026-05-15T06:14:38.626606",{"slug":4,"name":4,"fn":5,"description":6,"org":2343,"tags":2344,"stars":29,"repoUrl":30,"updatedAt":31},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2345,2346,2347,2348,2349],{"name":27,"slug":28,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":21,"slug":22,"type":16},{"slug":79,"name":79,"fn":2351,"description":2352,"org":2353,"tags":2354,"stars":29,"repoUrl":30,"updatedAt":2361},"set up Meta wearable SDK integration","SDK setup, Swift Package Manager integration, Info.plist configuration, and first connection to Meta glasses",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2355,2358,2359,2360],{"name":2356,"slug":2357,"type":16},"Configuration","configuration",{"name":2309,"slug":2310,"type":16},{"name":2324,"slug":2325,"type":16},{"name":2327,"slug":138,"type":16},"2026-05-15T06:14:41.086639",{"slug":2363,"name":2363,"fn":2364,"description":2365,"org":2366,"tags":2367,"stars":29,"repoUrl":30,"updatedAt":2376},"mockdevice-testing","test wearable apps with mock devices","MockDeviceKit for testing without physical glasses hardware",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2368,2369,2370,2373],{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},{"name":2371,"slug":2372,"type":16},"QA","qa",{"name":2374,"slug":2375,"type":16},"Testing","testing","2026-05-15T06:14:37.406692",{"slug":87,"name":87,"fn":2378,"description":2379,"org":2380,"tags":2381,"stars":29,"repoUrl":30,"updatedAt":2387},"register apps with Meta AI","App registration with Meta AI, camera permission flows",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2382,2383,2384],{"name":2303,"slug":2304,"type":16},{"name":2309,"slug":2310,"type":16},{"name":2385,"slug":2386,"type":16},"Permissions","permissions","2026-05-15T06:14:46.030253",{"items":2389,"total":859},[2390,2412,2426,2447,2454,2461,2467,2475,2482,2489,2495,2505],{"slug":2391,"name":2391,"fn":2392,"description":2393,"org":2394,"tags":2395,"stars":2409,"repoUrl":2410,"updatedAt":2411},"relay-best-practices","write idiomatic Relay code","Best practices for writing idiomatic Relay code. ALWAYS use this skill when writing or modifying React components that use Relay for data fetching. Covers fragments, queries, mutations, pagination, and common anti-patterns. Use when you see `useFragment`, `useLazyLoadQuery`, `usePreloadedQuery`, `useMutation`, `usePaginationFragment`, `graphql` template literals, `react-relay` imports, or `__generated__\u002F*.graphql` files. Also use when asked to explain Relay concepts, debug Relay issues, or review Relay code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2396,2397,2400,2403,2406],{"name":2338,"slug":2339,"type":16},{"name":2398,"slug":2399,"type":16},"Frontend","frontend",{"name":2401,"slug":2402,"type":16},"GraphQL","graphql",{"name":2404,"slug":2405,"type":16},"React","react",{"name":2407,"slug":2408,"type":16},"Relay","relay",18950,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Frelay","2026-04-22T04:58:15.370563",{"slug":2413,"name":2413,"fn":2414,"description":2415,"org":2416,"tags":2417,"stars":2409,"repoUrl":2410,"updatedAt":2425},"relay-performance","optimize Relay application performance","Performance best practices for Relay applications. Use when optimizing data fetching, reducing re-renders, configuring caching, or improving time to first meaningful paint. Covers query placement, @defer, pagination, fetch policies, garbage collection, fragment granularity, and server-side filtering. Companion to the relay-best-practices skill which covers correctness and architecture.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2418,2419,2420,2423,2424],{"name":2398,"slug":2399,"type":16},{"name":2401,"slug":2402,"type":16},{"name":2421,"slug":2422,"type":16},"Performance","performance",{"name":2404,"slug":2405,"type":16},{"name":2407,"slug":2408,"type":16},"2026-06-10T07:30:28.726513",{"slug":2427,"name":2427,"fn":2428,"description":2429,"org":2430,"tags":2431,"stars":2444,"repoUrl":2445,"updatedAt":2446},"add-shape-types-to-torch-model","annotate PyTorch models with tensor shapes","Port a PyTorch model to use pyrefly's tensor shape type system (Tensor[[B, C, H, W]], Int[T]). Use this skill whenever the user wants to add shape annotations to a PyTorch model, type a model with tensor dimensions, port a model to use shape tracking, or annotate model forward methods with tensor shapes. Also use when the user mentions tensor shape ports, Int types for PyTorch, or pyrefly shape checking on a model file. Invoke BEFORE starting any model port — the skill's gated workflow prevents common failure modes.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2432,2435,2438,2441],{"name":2433,"slug":2434,"type":16},"Data Modeling","data-modeling",{"name":2436,"slug":2437,"type":16},"Deep Learning","deep-learning",{"name":2439,"slug":2440,"type":16},"Python","python",{"name":2442,"slug":2443,"type":16},"PyTorch","pytorch",6833,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fpyrefly","2026-07-18T05:12:08.515952",{"slug":2297,"name":2297,"fn":2298,"description":2299,"org":2448,"tags":2449,"stars":29,"repoUrl":30,"updatedAt":2312},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2450,2451,2452,2453],{"name":2303,"slug":2304,"type":16},{"name":2306,"slug":2307,"type":16},{"name":2309,"slug":2310,"type":16},{"name":21,"slug":22,"type":16},{"slug":2314,"name":2314,"fn":2315,"description":2316,"org":2455,"tags":2456,"stars":29,"repoUrl":30,"updatedAt":2328},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2457,2458,2459,2460],{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},{"name":2324,"slug":2325,"type":16},{"name":2327,"slug":138,"type":16},{"slug":2330,"name":2330,"fn":2331,"description":2332,"org":2462,"tags":2463,"stars":29,"repoUrl":30,"updatedAt":2341},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2464,2465,2466],{"name":2336,"slug":2330,"type":16},{"name":2338,"slug":2339,"type":16},{"name":2309,"slug":2310,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":2468,"tags":2469,"stars":29,"repoUrl":30,"updatedAt":31},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2470,2471,2472,2473,2474],{"name":27,"slug":28,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":24,"slug":25,"type":16},{"name":21,"slug":22,"type":16},{"slug":79,"name":79,"fn":2351,"description":2352,"org":2476,"tags":2477,"stars":29,"repoUrl":30,"updatedAt":2361},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2478,2479,2480,2481],{"name":2356,"slug":2357,"type":16},{"name":2309,"slug":2310,"type":16},{"name":2324,"slug":2325,"type":16},{"name":2327,"slug":138,"type":16},{"slug":2363,"name":2363,"fn":2364,"description":2365,"org":2483,"tags":2484,"stars":29,"repoUrl":30,"updatedAt":2376},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2485,2486,2487,2488],{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},{"name":2371,"slug":2372,"type":16},{"name":2374,"slug":2375,"type":16},{"slug":87,"name":87,"fn":2378,"description":2379,"org":2490,"tags":2491,"stars":29,"repoUrl":30,"updatedAt":2387},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2492,2493,2494],{"name":2303,"slug":2304,"type":16},{"name":2309,"slug":2310,"type":16},{"name":2385,"slug":2386,"type":16},{"slug":2496,"name":2496,"fn":2497,"description":2498,"org":2499,"tags":2500,"stars":29,"repoUrl":30,"updatedAt":2504},"sample-app-guide","build wearable apps with camera streaming","Building a complete DAT app with camera streaming and photo capture",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2501,2502,2503],{"name":2303,"slug":2304,"type":16},{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},"2026-05-15T06:14:36.185947",{"slug":2506,"name":2506,"fn":2507,"description":2508,"org":2509,"tags":2510,"stars":29,"repoUrl":30,"updatedAt":2517},"session-lifecycle","monitor device session lifecycle states","Device session states, pause\u002Fresume, availability monitoring",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2511,2512,2513,2516],{"name":2309,"slug":2310,"type":16},{"name":2321,"slug":2322,"type":16},{"name":2514,"slug":2515,"type":16},"Monitoring","monitoring",{"name":2421,"slug":2422,"type":16},"2026-05-15T06:14:44.790925"]