[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-meta-mockdevice-testing":3,"mdc--xxxf6s-key":37,"related-org-meta-mockdevice-testing":871,"related-repo-meta-mockdevice-testing":1048},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":35,"mdContent":36},"mockdevice-testing","test wearable apps with mock devices","MockDeviceKit for testing without physical glasses hardware",{"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],{"name":14,"slug":15,"type":16},"iOS","ios","tag",{"name":18,"slug":19,"type":16},"QA","qa",{"name":21,"slug":22,"type":16},"Mobile","mobile",{"name":24,"slug":25,"type":16},"Testing","testing",488,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-dat-ios","2026-05-15T06:14:37.406692",null,112,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":34},[],"Meta Wearables Device Access Toolkit for iOS","https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-dat-ios\u002Ftree\u002FHEAD\u002Fplugins\u002Fmwdat-ios\u002Fskills\u002Fmockdevice-testing","---\nname: mockdevice-testing\ndescription: MockDeviceKit for testing without physical glasses hardware\n---\n\n# MockDevice Testing (iOS)\n\nUse MockDeviceKit to test DAT SDK integrations without physical Meta glasses.\n\nMockDeviceKit simulates Meta glasses behavior for development and testing. It provides:\n- `MockDeviceKit` — Entry point for creating simulated devices\n- `MockGlasses` — Simulated glasses (Ray-Ban Meta, etc.)\n- `MockCameraKit` — Simulated camera with configurable video feed and photo capture\n\n## Setup\n\nAdd `MWDATMockDevice` to your target via Swift Package Manager (it's included in the `meta-wearables-dat-ios` package).\n\n```swift\nimport MWDATMockDevice\n```\n\n## Creating a mock device\n\n```swift\nimport MWDATMockDevice\n\nlet mockDeviceKit = MockDeviceKit.shared\nmockDeviceKit.enable()\n\nlet mockDevice = try mockDeviceKit.pairGlasses(model: .rayBanMeta)\n```\n\n## Simulating device states\n\n```swift\n\u002F\u002F Simulate glasses lifecycle\nmockDevice.powerOn()\nmockDevice.unfold()\nmockDevice.don()    \u002F\u002F Simulate wearing the glasses\n\n\u002F\u002F Later...\nmockDevice.doff()   \u002F\u002F Simulate removing\nmockDevice.fold()\nmockDevice.powerOff()\n```\n\n## Configuring permissions\n\nMockDeviceKit provides `permissions` to control permission behavior without the Meta AI app.\n\nBy default, `requestPermission()` returns `.granted`. Use `set(_:_:)` to control `checkPermissionStatus()` and `setRequestResult(_:result:)` to control `requestPermission()` outcomes.\n\n```swift\nlet mockDeviceKit = MockDeviceKit.shared\n\n\u002F\u002F Simulate denied camera permission status\nmockDeviceKit.permissions.set(.camera, .denied)\n\n\u002F\u002F Simulate denied request result (user tapping \"deny\")\nmockDeviceKit.permissions.setRequestResult(.camera, result: .denied)\n```\n\n## Setting up mock camera feeds\n\n### Video streaming\n\n```swift\nlet camera = mockDevice.services.camera\ncamera.setCameraFeed(fileURL: videoURL)\n```\n\n### Photo capture\n\n```swift\nlet camera = mockDevice.services.camera\ncamera.setCapturedImage(fileURL: imageURL)\n```\n\n## Writing tests with MockDeviceKit\n\nCreate a reusable test base class:\n\n```swift\nimport XCTest\nimport MetaWearablesDAT\n\n@MainActor\nclass MockDeviceKitTestCase: XCTestCase {\n    private var mockDevice: MockGlasses?\n    private var cameraKit: MockCameraKit?\n\n    override func setUp() async throws {\n        try await super.setUp()\n        MockDeviceKit.shared.enable()\n        mockDevice = try MockDeviceKit.shared.pairGlasses(model: .rayBanMeta)\n        cameraKit = mockDevice?.services.camera \u002F\u002F mockDevice is MockGlasses? for tearDown nil-ability\n    }\n\n    override func tearDown() async throws {\n        MockDeviceKit.shared.disable()\n        mockDevice = nil\n        cameraKit = nil\n        try await super.tearDown()\n    }\n}\n```\n\n## Using MockDeviceKit in the CameraAccess sample\n\nThe CameraAccess sample app includes a Debug menu for MockDeviceKit:\n\n1. Tap the **Debug icon** to open the MockDeviceKit menu\n2. Tap **Pair RayBan Meta** to create a simulated device\n3. Use **PowerOn**, **Unfold**, **Don** to simulate glasses states\n4. Select video\u002Fimage files to configure mock camera feeds\n5. Start streaming to see simulated frames\n\n## Supported media formats\n\n| Type | Formats |\n|------|---------|\n| Video | h.265 (HEVC) |\n| Image | JPEG, PNG |\n\n## Links\n\n- [Mock Device Kit overview](https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Fmock-device-kit)\n- [iOS testing guide](https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Ftesting-mdk-ios)\n",{"data":38,"body":39},{"name":4,"description":6},{"type":40,"children":41},"root",[42,51,57,62,101,108,129,150,156,215,221,302,308,321,372,432,438,445,468,474,496,502,507,699,705,710,774,780,834,840,865],{"type":43,"tag":44,"props":45,"children":47},"element","h1",{"id":46},"mockdevice-testing-ios",[48],{"type":49,"value":50},"text","MockDevice Testing (iOS)",{"type":43,"tag":52,"props":53,"children":54},"p",{},[55],{"type":49,"value":56},"Use MockDeviceKit to test DAT SDK integrations without physical Meta glasses.",{"type":43,"tag":52,"props":58,"children":59},{},[60],{"type":49,"value":61},"MockDeviceKit simulates Meta glasses behavior for development and testing. It provides:",{"type":43,"tag":63,"props":64,"children":65},"ul",{},[66,79,90],{"type":43,"tag":67,"props":68,"children":69},"li",{},[70,77],{"type":43,"tag":71,"props":72,"children":74},"code",{"className":73},[],[75],{"type":49,"value":76},"MockDeviceKit",{"type":49,"value":78}," — Entry point for creating simulated devices",{"type":43,"tag":67,"props":80,"children":81},{},[82,88],{"type":43,"tag":71,"props":83,"children":85},{"className":84},[],[86],{"type":49,"value":87},"MockGlasses",{"type":49,"value":89}," — Simulated glasses (Ray-Ban Meta, etc.)",{"type":43,"tag":67,"props":91,"children":92},{},[93,99],{"type":43,"tag":71,"props":94,"children":96},{"className":95},[],[97],{"type":49,"value":98},"MockCameraKit",{"type":49,"value":100}," — Simulated camera with configurable video feed and photo capture",{"type":43,"tag":102,"props":103,"children":105},"h2",{"id":104},"setup",[106],{"type":49,"value":107},"Setup",{"type":43,"tag":52,"props":109,"children":110},{},[111,113,119,121,127],{"type":49,"value":112},"Add ",{"type":43,"tag":71,"props":114,"children":116},{"className":115},[],[117],{"type":49,"value":118},"MWDATMockDevice",{"type":49,"value":120}," to your target via Swift Package Manager (it's included in the ",{"type":43,"tag":71,"props":122,"children":124},{"className":123},[],[125],{"type":49,"value":126},"meta-wearables-dat-ios",{"type":49,"value":128}," package).",{"type":43,"tag":130,"props":131,"children":136},"pre",{"className":132,"code":133,"language":134,"meta":135,"style":135},"language-swift shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import MWDATMockDevice\n","swift","",[137],{"type":43,"tag":71,"props":138,"children":139},{"__ignoreMap":135},[140],{"type":43,"tag":141,"props":142,"children":145},"span",{"class":143,"line":144},"line",1,[146],{"type":43,"tag":141,"props":147,"children":148},{},[149],{"type":49,"value":133},{"type":43,"tag":102,"props":151,"children":153},{"id":152},"creating-a-mock-device",[154],{"type":49,"value":155},"Creating a mock device",{"type":43,"tag":130,"props":157,"children":159},{"className":132,"code":158,"language":134,"meta":135,"style":135},"import MWDATMockDevice\n\nlet mockDeviceKit = MockDeviceKit.shared\nmockDeviceKit.enable()\n\nlet mockDevice = try mockDeviceKit.pairGlasses(model: .rayBanMeta)\n",[160],{"type":43,"tag":71,"props":161,"children":162},{"__ignoreMap":135},[163,170,180,189,198,206],{"type":43,"tag":141,"props":164,"children":165},{"class":143,"line":144},[166],{"type":43,"tag":141,"props":167,"children":168},{},[169],{"type":49,"value":133},{"type":43,"tag":141,"props":171,"children":173},{"class":143,"line":172},2,[174],{"type":43,"tag":141,"props":175,"children":177},{"emptyLinePlaceholder":176},true,[178],{"type":49,"value":179},"\n",{"type":43,"tag":141,"props":181,"children":183},{"class":143,"line":182},3,[184],{"type":43,"tag":141,"props":185,"children":186},{},[187],{"type":49,"value":188},"let mockDeviceKit = MockDeviceKit.shared\n",{"type":43,"tag":141,"props":190,"children":192},{"class":143,"line":191},4,[193],{"type":43,"tag":141,"props":194,"children":195},{},[196],{"type":49,"value":197},"mockDeviceKit.enable()\n",{"type":43,"tag":141,"props":199,"children":201},{"class":143,"line":200},5,[202],{"type":43,"tag":141,"props":203,"children":204},{"emptyLinePlaceholder":176},[205],{"type":49,"value":179},{"type":43,"tag":141,"props":207,"children":209},{"class":143,"line":208},6,[210],{"type":43,"tag":141,"props":211,"children":212},{},[213],{"type":49,"value":214},"let mockDevice = try mockDeviceKit.pairGlasses(model: .rayBanMeta)\n",{"type":43,"tag":102,"props":216,"children":218},{"id":217},"simulating-device-states",[219],{"type":49,"value":220},"Simulating device states",{"type":43,"tag":130,"props":222,"children":224},{"className":132,"code":223,"language":134,"meta":135,"style":135},"\u002F\u002F Simulate glasses lifecycle\nmockDevice.powerOn()\nmockDevice.unfold()\nmockDevice.don()    \u002F\u002F Simulate wearing the glasses\n\n\u002F\u002F Later...\nmockDevice.doff()   \u002F\u002F Simulate removing\nmockDevice.fold()\nmockDevice.powerOff()\n",[225],{"type":43,"tag":71,"props":226,"children":227},{"__ignoreMap":135},[228,236,244,252,260,267,275,284,293],{"type":43,"tag":141,"props":229,"children":230},{"class":143,"line":144},[231],{"type":43,"tag":141,"props":232,"children":233},{},[234],{"type":49,"value":235},"\u002F\u002F Simulate glasses lifecycle\n",{"type":43,"tag":141,"props":237,"children":238},{"class":143,"line":172},[239],{"type":43,"tag":141,"props":240,"children":241},{},[242],{"type":49,"value":243},"mockDevice.powerOn()\n",{"type":43,"tag":141,"props":245,"children":246},{"class":143,"line":182},[247],{"type":43,"tag":141,"props":248,"children":249},{},[250],{"type":49,"value":251},"mockDevice.unfold()\n",{"type":43,"tag":141,"props":253,"children":254},{"class":143,"line":191},[255],{"type":43,"tag":141,"props":256,"children":257},{},[258],{"type":49,"value":259},"mockDevice.don()    \u002F\u002F Simulate wearing the glasses\n",{"type":43,"tag":141,"props":261,"children":262},{"class":143,"line":200},[263],{"type":43,"tag":141,"props":264,"children":265},{"emptyLinePlaceholder":176},[266],{"type":49,"value":179},{"type":43,"tag":141,"props":268,"children":269},{"class":143,"line":208},[270],{"type":43,"tag":141,"props":271,"children":272},{},[273],{"type":49,"value":274},"\u002F\u002F Later...\n",{"type":43,"tag":141,"props":276,"children":278},{"class":143,"line":277},7,[279],{"type":43,"tag":141,"props":280,"children":281},{},[282],{"type":49,"value":283},"mockDevice.doff()   \u002F\u002F Simulate removing\n",{"type":43,"tag":141,"props":285,"children":287},{"class":143,"line":286},8,[288],{"type":43,"tag":141,"props":289,"children":290},{},[291],{"type":49,"value":292},"mockDevice.fold()\n",{"type":43,"tag":141,"props":294,"children":296},{"class":143,"line":295},9,[297],{"type":43,"tag":141,"props":298,"children":299},{},[300],{"type":49,"value":301},"mockDevice.powerOff()\n",{"type":43,"tag":102,"props":303,"children":305},{"id":304},"configuring-permissions",[306],{"type":49,"value":307},"Configuring permissions",{"type":43,"tag":52,"props":309,"children":310},{},[311,313,319],{"type":49,"value":312},"MockDeviceKit provides ",{"type":43,"tag":71,"props":314,"children":316},{"className":315},[],[317],{"type":49,"value":318},"permissions",{"type":49,"value":320}," to control permission behavior without the Meta AI app.",{"type":43,"tag":52,"props":322,"children":323},{},[324,326,332,334,340,342,348,350,356,358,364,365,370],{"type":49,"value":325},"By default, ",{"type":43,"tag":71,"props":327,"children":329},{"className":328},[],[330],{"type":49,"value":331},"requestPermission()",{"type":49,"value":333}," returns ",{"type":43,"tag":71,"props":335,"children":337},{"className":336},[],[338],{"type":49,"value":339},".granted",{"type":49,"value":341},". Use ",{"type":43,"tag":71,"props":343,"children":345},{"className":344},[],[346],{"type":49,"value":347},"set(_:_:)",{"type":49,"value":349}," to control ",{"type":43,"tag":71,"props":351,"children":353},{"className":352},[],[354],{"type":49,"value":355},"checkPermissionStatus()",{"type":49,"value":357}," and ",{"type":43,"tag":71,"props":359,"children":361},{"className":360},[],[362],{"type":49,"value":363},"setRequestResult(_:result:)",{"type":49,"value":349},{"type":43,"tag":71,"props":366,"children":368},{"className":367},[],[369],{"type":49,"value":331},{"type":49,"value":371}," outcomes.",{"type":43,"tag":130,"props":373,"children":375},{"className":132,"code":374,"language":134,"meta":135,"style":135},"let mockDeviceKit = MockDeviceKit.shared\n\n\u002F\u002F Simulate denied camera permission status\nmockDeviceKit.permissions.set(.camera, .denied)\n\n\u002F\u002F Simulate denied request result (user tapping \"deny\")\nmockDeviceKit.permissions.setRequestResult(.camera, result: .denied)\n",[376],{"type":43,"tag":71,"props":377,"children":378},{"__ignoreMap":135},[379,386,393,401,409,416,424],{"type":43,"tag":141,"props":380,"children":381},{"class":143,"line":144},[382],{"type":43,"tag":141,"props":383,"children":384},{},[385],{"type":49,"value":188},{"type":43,"tag":141,"props":387,"children":388},{"class":143,"line":172},[389],{"type":43,"tag":141,"props":390,"children":391},{"emptyLinePlaceholder":176},[392],{"type":49,"value":179},{"type":43,"tag":141,"props":394,"children":395},{"class":143,"line":182},[396],{"type":43,"tag":141,"props":397,"children":398},{},[399],{"type":49,"value":400},"\u002F\u002F Simulate denied camera permission status\n",{"type":43,"tag":141,"props":402,"children":403},{"class":143,"line":191},[404],{"type":43,"tag":141,"props":405,"children":406},{},[407],{"type":49,"value":408},"mockDeviceKit.permissions.set(.camera, .denied)\n",{"type":43,"tag":141,"props":410,"children":411},{"class":143,"line":200},[412],{"type":43,"tag":141,"props":413,"children":414},{"emptyLinePlaceholder":176},[415],{"type":49,"value":179},{"type":43,"tag":141,"props":417,"children":418},{"class":143,"line":208},[419],{"type":43,"tag":141,"props":420,"children":421},{},[422],{"type":49,"value":423},"\u002F\u002F Simulate denied request result (user tapping \"deny\")\n",{"type":43,"tag":141,"props":425,"children":426},{"class":143,"line":277},[427],{"type":43,"tag":141,"props":428,"children":429},{},[430],{"type":49,"value":431},"mockDeviceKit.permissions.setRequestResult(.camera, result: .denied)\n",{"type":43,"tag":102,"props":433,"children":435},{"id":434},"setting-up-mock-camera-feeds",[436],{"type":49,"value":437},"Setting up mock camera feeds",{"type":43,"tag":439,"props":440,"children":442},"h3",{"id":441},"video-streaming",[443],{"type":49,"value":444},"Video streaming",{"type":43,"tag":130,"props":446,"children":448},{"className":132,"code":447,"language":134,"meta":135,"style":135},"let camera = mockDevice.services.camera\ncamera.setCameraFeed(fileURL: videoURL)\n",[449],{"type":43,"tag":71,"props":450,"children":451},{"__ignoreMap":135},[452,460],{"type":43,"tag":141,"props":453,"children":454},{"class":143,"line":144},[455],{"type":43,"tag":141,"props":456,"children":457},{},[458],{"type":49,"value":459},"let camera = mockDevice.services.camera\n",{"type":43,"tag":141,"props":461,"children":462},{"class":143,"line":172},[463],{"type":43,"tag":141,"props":464,"children":465},{},[466],{"type":49,"value":467},"camera.setCameraFeed(fileURL: videoURL)\n",{"type":43,"tag":439,"props":469,"children":471},{"id":470},"photo-capture",[472],{"type":49,"value":473},"Photo capture",{"type":43,"tag":130,"props":475,"children":477},{"className":132,"code":476,"language":134,"meta":135,"style":135},"let camera = mockDevice.services.camera\ncamera.setCapturedImage(fileURL: imageURL)\n",[478],{"type":43,"tag":71,"props":479,"children":480},{"__ignoreMap":135},[481,488],{"type":43,"tag":141,"props":482,"children":483},{"class":143,"line":144},[484],{"type":43,"tag":141,"props":485,"children":486},{},[487],{"type":49,"value":459},{"type":43,"tag":141,"props":489,"children":490},{"class":143,"line":172},[491],{"type":43,"tag":141,"props":492,"children":493},{},[494],{"type":49,"value":495},"camera.setCapturedImage(fileURL: imageURL)\n",{"type":43,"tag":102,"props":497,"children":499},{"id":498},"writing-tests-with-mockdevicekit",[500],{"type":49,"value":501},"Writing tests with MockDeviceKit",{"type":43,"tag":52,"props":503,"children":504},{},[505],{"type":49,"value":506},"Create a reusable test base class:",{"type":43,"tag":130,"props":508,"children":510},{"className":132,"code":509,"language":134,"meta":135,"style":135},"import XCTest\nimport MetaWearablesDAT\n\n@MainActor\nclass MockDeviceKitTestCase: XCTestCase {\n    private var mockDevice: MockGlasses?\n    private var cameraKit: MockCameraKit?\n\n    override func setUp() async throws {\n        try await super.setUp()\n        MockDeviceKit.shared.enable()\n        mockDevice = try MockDeviceKit.shared.pairGlasses(model: .rayBanMeta)\n        cameraKit = mockDevice?.services.camera \u002F\u002F mockDevice is MockGlasses? for tearDown nil-ability\n    }\n\n    override func tearDown() async throws {\n        MockDeviceKit.shared.disable()\n        mockDevice = nil\n        cameraKit = nil\n        try await super.tearDown()\n    }\n}\n",[511],{"type":43,"tag":71,"props":512,"children":513},{"__ignoreMap":135},[514,522,530,537,545,553,561,569,576,584,593,602,611,620,629,637,646,655,664,673,682,690],{"type":43,"tag":141,"props":515,"children":516},{"class":143,"line":144},[517],{"type":43,"tag":141,"props":518,"children":519},{},[520],{"type":49,"value":521},"import XCTest\n",{"type":43,"tag":141,"props":523,"children":524},{"class":143,"line":172},[525],{"type":43,"tag":141,"props":526,"children":527},{},[528],{"type":49,"value":529},"import MetaWearablesDAT\n",{"type":43,"tag":141,"props":531,"children":532},{"class":143,"line":182},[533],{"type":43,"tag":141,"props":534,"children":535},{"emptyLinePlaceholder":176},[536],{"type":49,"value":179},{"type":43,"tag":141,"props":538,"children":539},{"class":143,"line":191},[540],{"type":43,"tag":141,"props":541,"children":542},{},[543],{"type":49,"value":544},"@MainActor\n",{"type":43,"tag":141,"props":546,"children":547},{"class":143,"line":200},[548],{"type":43,"tag":141,"props":549,"children":550},{},[551],{"type":49,"value":552},"class MockDeviceKitTestCase: XCTestCase {\n",{"type":43,"tag":141,"props":554,"children":555},{"class":143,"line":208},[556],{"type":43,"tag":141,"props":557,"children":558},{},[559],{"type":49,"value":560},"    private var mockDevice: MockGlasses?\n",{"type":43,"tag":141,"props":562,"children":563},{"class":143,"line":277},[564],{"type":43,"tag":141,"props":565,"children":566},{},[567],{"type":49,"value":568},"    private var cameraKit: MockCameraKit?\n",{"type":43,"tag":141,"props":570,"children":571},{"class":143,"line":286},[572],{"type":43,"tag":141,"props":573,"children":574},{"emptyLinePlaceholder":176},[575],{"type":49,"value":179},{"type":43,"tag":141,"props":577,"children":578},{"class":143,"line":295},[579],{"type":43,"tag":141,"props":580,"children":581},{},[582],{"type":49,"value":583},"    override func setUp() async throws {\n",{"type":43,"tag":141,"props":585,"children":587},{"class":143,"line":586},10,[588],{"type":43,"tag":141,"props":589,"children":590},{},[591],{"type":49,"value":592},"        try await super.setUp()\n",{"type":43,"tag":141,"props":594,"children":596},{"class":143,"line":595},11,[597],{"type":43,"tag":141,"props":598,"children":599},{},[600],{"type":49,"value":601},"        MockDeviceKit.shared.enable()\n",{"type":43,"tag":141,"props":603,"children":605},{"class":143,"line":604},12,[606],{"type":43,"tag":141,"props":607,"children":608},{},[609],{"type":49,"value":610},"        mockDevice = try MockDeviceKit.shared.pairGlasses(model: .rayBanMeta)\n",{"type":43,"tag":141,"props":612,"children":614},{"class":143,"line":613},13,[615],{"type":43,"tag":141,"props":616,"children":617},{},[618],{"type":49,"value":619},"        cameraKit = mockDevice?.services.camera \u002F\u002F mockDevice is MockGlasses? for tearDown nil-ability\n",{"type":43,"tag":141,"props":621,"children":623},{"class":143,"line":622},14,[624],{"type":43,"tag":141,"props":625,"children":626},{},[627],{"type":49,"value":628},"    }\n",{"type":43,"tag":141,"props":630,"children":632},{"class":143,"line":631},15,[633],{"type":43,"tag":141,"props":634,"children":635},{"emptyLinePlaceholder":176},[636],{"type":49,"value":179},{"type":43,"tag":141,"props":638,"children":640},{"class":143,"line":639},16,[641],{"type":43,"tag":141,"props":642,"children":643},{},[644],{"type":49,"value":645},"    override func tearDown() async throws {\n",{"type":43,"tag":141,"props":647,"children":649},{"class":143,"line":648},17,[650],{"type":43,"tag":141,"props":651,"children":652},{},[653],{"type":49,"value":654},"        MockDeviceKit.shared.disable()\n",{"type":43,"tag":141,"props":656,"children":658},{"class":143,"line":657},18,[659],{"type":43,"tag":141,"props":660,"children":661},{},[662],{"type":49,"value":663},"        mockDevice = nil\n",{"type":43,"tag":141,"props":665,"children":667},{"class":143,"line":666},19,[668],{"type":43,"tag":141,"props":669,"children":670},{},[671],{"type":49,"value":672},"        cameraKit = nil\n",{"type":43,"tag":141,"props":674,"children":676},{"class":143,"line":675},20,[677],{"type":43,"tag":141,"props":678,"children":679},{},[680],{"type":49,"value":681},"        try await super.tearDown()\n",{"type":43,"tag":141,"props":683,"children":685},{"class":143,"line":684},21,[686],{"type":43,"tag":141,"props":687,"children":688},{},[689],{"type":49,"value":628},{"type":43,"tag":141,"props":691,"children":693},{"class":143,"line":692},22,[694],{"type":43,"tag":141,"props":695,"children":696},{},[697],{"type":49,"value":698},"}\n",{"type":43,"tag":102,"props":700,"children":702},{"id":701},"using-mockdevicekit-in-the-cameraaccess-sample",[703],{"type":49,"value":704},"Using MockDeviceKit in the CameraAccess sample",{"type":43,"tag":52,"props":706,"children":707},{},[708],{"type":49,"value":709},"The CameraAccess sample app includes a Debug menu for MockDeviceKit:",{"type":43,"tag":711,"props":712,"children":713},"ol",{},[714,727,739,764,769],{"type":43,"tag":67,"props":715,"children":716},{},[717,719,725],{"type":49,"value":718},"Tap the ",{"type":43,"tag":720,"props":721,"children":722},"strong",{},[723],{"type":49,"value":724},"Debug icon",{"type":49,"value":726}," to open the MockDeviceKit menu",{"type":43,"tag":67,"props":728,"children":729},{},[730,732,737],{"type":49,"value":731},"Tap ",{"type":43,"tag":720,"props":733,"children":734},{},[735],{"type":49,"value":736},"Pair RayBan Meta",{"type":49,"value":738}," to create a simulated device",{"type":43,"tag":67,"props":740,"children":741},{},[742,744,749,751,756,757,762],{"type":49,"value":743},"Use ",{"type":43,"tag":720,"props":745,"children":746},{},[747],{"type":49,"value":748},"PowerOn",{"type":49,"value":750},", ",{"type":43,"tag":720,"props":752,"children":753},{},[754],{"type":49,"value":755},"Unfold",{"type":49,"value":750},{"type":43,"tag":720,"props":758,"children":759},{},[760],{"type":49,"value":761},"Don",{"type":49,"value":763}," to simulate glasses states",{"type":43,"tag":67,"props":765,"children":766},{},[767],{"type":49,"value":768},"Select video\u002Fimage files to configure mock camera feeds",{"type":43,"tag":67,"props":770,"children":771},{},[772],{"type":49,"value":773},"Start streaming to see simulated frames",{"type":43,"tag":102,"props":775,"children":777},{"id":776},"supported-media-formats",[778],{"type":49,"value":779},"Supported media formats",{"type":43,"tag":781,"props":782,"children":783},"table",{},[784,803],{"type":43,"tag":785,"props":786,"children":787},"thead",{},[788],{"type":43,"tag":789,"props":790,"children":791},"tr",{},[792,798],{"type":43,"tag":793,"props":794,"children":795},"th",{},[796],{"type":49,"value":797},"Type",{"type":43,"tag":793,"props":799,"children":800},{},[801],{"type":49,"value":802},"Formats",{"type":43,"tag":804,"props":805,"children":806},"tbody",{},[807,821],{"type":43,"tag":789,"props":808,"children":809},{},[810,816],{"type":43,"tag":811,"props":812,"children":813},"td",{},[814],{"type":49,"value":815},"Video",{"type":43,"tag":811,"props":817,"children":818},{},[819],{"type":49,"value":820},"h.265 (HEVC)",{"type":43,"tag":789,"props":822,"children":823},{},[824,829],{"type":43,"tag":811,"props":825,"children":826},{},[827],{"type":49,"value":828},"Image",{"type":43,"tag":811,"props":830,"children":831},{},[832],{"type":49,"value":833},"JPEG, PNG",{"type":43,"tag":102,"props":835,"children":837},{"id":836},"links",[838],{"type":49,"value":839},"Links",{"type":43,"tag":63,"props":841,"children":842},{},[843,855],{"type":43,"tag":67,"props":844,"children":845},{},[846],{"type":43,"tag":847,"props":848,"children":852},"a",{"href":849,"rel":850},"https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Fmock-device-kit",[851],"nofollow",[853],{"type":49,"value":854},"Mock Device Kit overview",{"type":43,"tag":67,"props":856,"children":857},{},[858],{"type":43,"tag":847,"props":859,"children":862},{"href":860,"rel":861},"https:\u002F\u002Fwearables.developer.meta.com\u002Fdocs\u002Ftesting-mdk-ios",[851],[863],{"type":49,"value":864},"iOS testing guide",{"type":43,"tag":866,"props":867,"children":868},"style",{},[869],{"type":49,"value":870},"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":872,"total":1047},[873,897,911,932,948,962,973,993,1006,1013,1024,1034],{"slug":874,"name":874,"fn":875,"description":876,"org":877,"tags":878,"stars":894,"repoUrl":895,"updatedAt":896},"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},[879,882,885,888,891],{"name":880,"slug":881,"type":16},"Engineering","engineering",{"name":883,"slug":884,"type":16},"Frontend","frontend",{"name":886,"slug":887,"type":16},"GraphQL","graphql",{"name":889,"slug":890,"type":16},"React","react",{"name":892,"slug":893,"type":16},"Relay","relay",18950,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Frelay","2026-04-22T04:58:15.370563",{"slug":898,"name":898,"fn":899,"description":900,"org":901,"tags":902,"stars":894,"repoUrl":895,"updatedAt":910},"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},[903,904,905,908,909],{"name":883,"slug":884,"type":16},{"name":886,"slug":887,"type":16},{"name":906,"slug":907,"type":16},"Performance","performance",{"name":889,"slug":890,"type":16},{"name":892,"slug":893,"type":16},"2026-06-10T07:30:28.726513",{"slug":912,"name":912,"fn":913,"description":914,"org":915,"tags":916,"stars":929,"repoUrl":930,"updatedAt":931},"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},[917,920,923,926],{"name":918,"slug":919,"type":16},"Data Modeling","data-modeling",{"name":921,"slug":922,"type":16},"Deep Learning","deep-learning",{"name":924,"slug":925,"type":16},"Python","python",{"name":927,"slug":928,"type":16},"PyTorch","pytorch",6833,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fpyrefly","2026-07-18T05:12:08.515952",{"slug":933,"name":933,"fn":934,"description":935,"org":936,"tags":937,"stars":26,"repoUrl":27,"updatedAt":947},"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},[938,941,944,945],{"name":939,"slug":940,"type":16},"Camera","camera",{"name":942,"slug":943,"type":16},"Hardware","hardware",{"name":14,"slug":15,"type":16},{"name":815,"slug":946,"type":16},"video","2026-05-15T06:14:43.555881",{"slug":949,"name":949,"fn":950,"description":951,"org":952,"tags":953,"stars":26,"repoUrl":27,"updatedAt":961},"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},[954,955,956,959],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":957,"slug":958,"type":16},"SDK","sdk",{"name":960,"slug":134,"type":16},"Swift","2026-05-15T06:14:42.334435",{"slug":963,"name":963,"fn":964,"description":965,"org":966,"tags":967,"stars":26,"repoUrl":27,"updatedAt":972},"debugging","debug wearable device software","Common issues, Developer Mode, version compatibility, state machine diagnosis",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[968,970,971],{"name":969,"slug":963,"type":16},"Debugging",{"name":880,"slug":881,"type":16},{"name":14,"slug":15,"type":16},"2026-05-15T06:14:38.626606",{"slug":974,"name":974,"fn":975,"description":976,"org":977,"tags":978,"stars":26,"repoUrl":27,"updatedAt":992},"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},[979,982,985,988,991],{"name":980,"slug":981,"type":16},"Design","design",{"name":983,"slug":984,"type":16},"Images","images",{"name":986,"slug":987,"type":16},"Interaction","interaction",{"name":989,"slug":990,"type":16},"UI Components","ui-components",{"name":815,"slug":946,"type":16},"2026-05-15T06:14:39.844502",{"slug":994,"name":994,"fn":995,"description":996,"org":997,"tags":998,"stars":26,"repoUrl":27,"updatedAt":1005},"getting-started","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},[999,1002,1003,1004],{"name":1000,"slug":1001,"type":16},"Configuration","configuration",{"name":14,"slug":15,"type":16},{"name":957,"slug":958,"type":16},{"name":960,"slug":134,"type":16},"2026-05-15T06:14:41.086639",{"slug":4,"name":4,"fn":5,"description":6,"org":1007,"tags":1008,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1009,1010,1011,1012],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":24,"slug":25,"type":16},{"slug":1014,"name":1014,"fn":1015,"description":1016,"org":1017,"tags":1018,"stars":26,"repoUrl":27,"updatedAt":1023},"permissions-registration","register apps with Meta AI","App registration with Meta AI, camera permission flows",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1019,1020,1021],{"name":939,"slug":940,"type":16},{"name":14,"slug":15,"type":16},{"name":1022,"slug":318,"type":16},"Permissions","2026-05-15T06:14:46.030253",{"slug":1025,"name":1025,"fn":1026,"description":1027,"org":1028,"tags":1029,"stars":26,"repoUrl":27,"updatedAt":1033},"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},[1030,1031,1032],{"name":939,"slug":940,"type":16},{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},"2026-05-15T06:14:36.185947",{"slug":1035,"name":1035,"fn":1036,"description":1037,"org":1038,"tags":1039,"stars":26,"repoUrl":27,"updatedAt":1046},"session-lifecycle","monitor device session lifecycle states","Device session states, pause\u002Fresume, availability monitoring",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1040,1041,1042,1045],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":1043,"slug":1044,"type":16},"Monitoring","monitoring",{"name":906,"slug":907,"type":16},"2026-05-15T06:14:44.790925",27,{"items":1049,"total":295},[1050,1057,1064,1070,1078,1085,1092],{"slug":933,"name":933,"fn":934,"description":935,"org":1051,"tags":1052,"stars":26,"repoUrl":27,"updatedAt":947},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1053,1054,1055,1056],{"name":939,"slug":940,"type":16},{"name":942,"slug":943,"type":16},{"name":14,"slug":15,"type":16},{"name":815,"slug":946,"type":16},{"slug":949,"name":949,"fn":950,"description":951,"org":1058,"tags":1059,"stars":26,"repoUrl":27,"updatedAt":961},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1060,1061,1062,1063],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":957,"slug":958,"type":16},{"name":960,"slug":134,"type":16},{"slug":963,"name":963,"fn":964,"description":965,"org":1065,"tags":1066,"stars":26,"repoUrl":27,"updatedAt":972},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1067,1068,1069],{"name":969,"slug":963,"type":16},{"name":880,"slug":881,"type":16},{"name":14,"slug":15,"type":16},{"slug":974,"name":974,"fn":975,"description":976,"org":1071,"tags":1072,"stars":26,"repoUrl":27,"updatedAt":992},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1073,1074,1075,1076,1077],{"name":980,"slug":981,"type":16},{"name":983,"slug":984,"type":16},{"name":986,"slug":987,"type":16},{"name":989,"slug":990,"type":16},{"name":815,"slug":946,"type":16},{"slug":994,"name":994,"fn":995,"description":996,"org":1079,"tags":1080,"stars":26,"repoUrl":27,"updatedAt":1005},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1081,1082,1083,1084],{"name":1000,"slug":1001,"type":16},{"name":14,"slug":15,"type":16},{"name":957,"slug":958,"type":16},{"name":960,"slug":134,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":1086,"tags":1087,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1088,1089,1090,1091],{"name":14,"slug":15,"type":16},{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":24,"slug":25,"type":16},{"slug":1014,"name":1014,"fn":1015,"description":1016,"org":1093,"tags":1094,"stars":26,"repoUrl":27,"updatedAt":1023},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1095,1096,1097],{"name":939,"slug":940,"type":16},{"name":14,"slug":15,"type":16},{"name":1022,"slug":318,"type":16}]