[{"data":1,"prerenderedAt":513},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fsdks\u002Fswift":3},{"id":4,"title":5,"body":6,"description":506,"extension":507,"meta":508,"navigation":147,"path":509,"seo":510,"stem":511,"__hash__":512},"content\u002Fdocs\u002Fsdks\u002Fswift.md","Swift SDK",{"type":7,"value":8,"toc":497},"minimark",[9,13,21,26,33,110,118,129,133,251,255,265,317,348,352,358,394,398,457,461,479,483,493],[10,11,5],"h1",{"id":12},"swift-sdk",[14,15,16,20],"p",{},[17,18,19],"code",{},"ConduytKit"," is the official Swift SDK. It uses async\u002Fawait throughout, ships as a Swift Package, and is built for iOS \u002F macOS \u002F iPadOS apps that want to talk to CONDUYT-firmware boards over Bluetooth LE or USB-serial bridges.",[22,23,25],"h2",{"id":24},"install","Install",[14,27,28,29,32],{},"Add the package to your ",[17,30,31],{},"Package.swift",":",[34,35,40],"pre",{"className":36,"code":37,"language":38,"meta":39,"style":39},"language-swift shiki shiki-themes github-light github-dark","dependencies: [\n    .package(url: \"https:\u002F\u002Fgithub.com\u002Fvirgilvox\u002Fconduyt.git\", from: \"1.0.0\"),\n],\ntargets: [\n    .target(\n        name: \"MyApp\",\n        dependencies: [\n            .product(name: \"ConduytKit\", package: \"conduyt\"),\n        ]\n    ),\n]\n","swift","",[17,41,42,50,56,62,68,74,80,86,92,98,104],{"__ignoreMap":39},[43,44,47],"span",{"class":45,"line":46},"line",1,[43,48,49],{},"dependencies: [\n",[43,51,53],{"class":45,"line":52},2,[43,54,55],{},"    .package(url: \"https:\u002F\u002Fgithub.com\u002Fvirgilvox\u002Fconduyt.git\", from: \"1.0.0\"),\n",[43,57,59],{"class":45,"line":58},3,[43,60,61],{},"],\n",[43,63,65],{"class":45,"line":64},4,[43,66,67],{},"targets: [\n",[43,69,71],{"class":45,"line":70},5,[43,72,73],{},"    .target(\n",[43,75,77],{"class":45,"line":76},6,[43,78,79],{},"        name: \"MyApp\",\n",[43,81,83],{"class":45,"line":82},7,[43,84,85],{},"        dependencies: [\n",[43,87,89],{"class":45,"line":88},8,[43,90,91],{},"            .product(name: \"ConduytKit\", package: \"conduyt\"),\n",[43,93,95],{"class":45,"line":94},9,[43,96,97],{},"        ]\n",[43,99,101],{"class":45,"line":100},10,[43,102,103],{},"    ),\n",[43,105,107],{"class":45,"line":106},11,[43,108,109],{},"]\n",[14,111,112,113,117],{},"In Xcode: ",[114,115,116],"strong",{},"File → Add Package Dependencies…"," → paste the GitHub URL.",[14,119,120,121,124,125,128],{},"Minimum platforms: iOS 15, macOS 12 (",[17,122,123],{},"async","\u002F",[17,126,127],{},"await"," requires it).",[22,130,132],{"id":131},"quick-start-ble","Quick start (BLE)",[34,134,136],{"className":36,"code":135,"language":38,"meta":39,"style":39},"import ConduytKit\n\n\u002F\u002F BLETransport(name: String? = nil, uuid: UUID? = nil). Pass `name:` to filter\n\u002F\u002F the picker by advertised name, `uuid:` to target a specific device, or\n\u002F\u002F neither to take the first CONDUYT-service advertiser.\nlet transport = BLETransport()\nlet device = ConduytDevice(transport: transport)\n\nTask {\n    do {\n        let hello = try await device.connect()\n        print(\"connected, \\(hello.count) bytes of HELLO_RESP\")\n\n        try await device.pinMode(13, mode: ConduytPinMode.output)\n        try await device.pinWrite(13, value: 1)\n\n        try await device.disconnect()\n    } catch {\n        print(\"error: \\(error)\")\n    }\n}\n",[17,137,138,143,149,154,159,164,169,174,178,183,188,193,199,204,210,216,221,227,233,239,245],{"__ignoreMap":39},[43,139,140],{"class":45,"line":46},[43,141,142],{},"import ConduytKit\n",[43,144,145],{"class":45,"line":52},[43,146,148],{"emptyLinePlaceholder":147},true,"\n",[43,150,151],{"class":45,"line":58},[43,152,153],{},"\u002F\u002F BLETransport(name: String? = nil, uuid: UUID? = nil). Pass `name:` to filter\n",[43,155,156],{"class":45,"line":64},[43,157,158],{},"\u002F\u002F the picker by advertised name, `uuid:` to target a specific device, or\n",[43,160,161],{"class":45,"line":70},[43,162,163],{},"\u002F\u002F neither to take the first CONDUYT-service advertiser.\n",[43,165,166],{"class":45,"line":76},[43,167,168],{},"let transport = BLETransport()\n",[43,170,171],{"class":45,"line":82},[43,172,173],{},"let device = ConduytDevice(transport: transport)\n",[43,175,176],{"class":45,"line":88},[43,177,148],{"emptyLinePlaceholder":147},[43,179,180],{"class":45,"line":94},[43,181,182],{},"Task {\n",[43,184,185],{"class":45,"line":100},[43,186,187],{},"    do {\n",[43,189,190],{"class":45,"line":106},[43,191,192],{},"        let hello = try await device.connect()\n",[43,194,196],{"class":45,"line":195},12,[43,197,198],{},"        print(\"connected, \\(hello.count) bytes of HELLO_RESP\")\n",[43,200,202],{"class":45,"line":201},13,[43,203,148],{"emptyLinePlaceholder":147},[43,205,207],{"class":45,"line":206},14,[43,208,209],{},"        try await device.pinMode(13, mode: ConduytPinMode.output)\n",[43,211,213],{"class":45,"line":212},15,[43,214,215],{},"        try await device.pinWrite(13, value: 1)\n",[43,217,219],{"class":45,"line":218},16,[43,220,148],{"emptyLinePlaceholder":147},[43,222,224],{"class":45,"line":223},17,[43,225,226],{},"        try await device.disconnect()\n",[43,228,230],{"class":45,"line":229},18,[43,231,232],{},"    } catch {\n",[43,234,236],{"class":45,"line":235},19,[43,237,238],{},"        print(\"error: \\(error)\")\n",[43,240,242],{"class":45,"line":241},20,[43,243,244],{},"    }\n",[43,246,248],{"class":45,"line":247},21,[43,249,250],{},"}\n",[22,252,254],{"id":253},"modules","Modules",[14,256,257,258,261,262,32],{},"Module wrappers are in ",[17,259,260],{},"ConduytKit.Modules",". Each wraps a connected device and a ",[17,263,264],{},"moduleID",[34,266,268],{"className":36,"code":267,"language":38,"meta":39,"style":39},"import ConduytKit\n\nlet servo = ConduytServo(device: device, moduleID: 0)\ntry await servo.attach(pin: 9, minUs: 1000, maxUs: 2000)\ntry await servo.write(angle: 90)\n\nlet neo = ConduytNeoPixel(device: device, moduleID: 1)\ntry await neo.begin(pin: 6, count: 64)\ntry await neo.fill(r: 0, g: 255, b: 0)\ntry await neo.show()\n",[17,269,270,274,278,283,288,293,297,302,307,312],{"__ignoreMap":39},[43,271,272],{"class":45,"line":46},[43,273,142],{},[43,275,276],{"class":45,"line":52},[43,277,148],{"emptyLinePlaceholder":147},[43,279,280],{"class":45,"line":58},[43,281,282],{},"let servo = ConduytServo(device: device, moduleID: 0)\n",[43,284,285],{"class":45,"line":64},[43,286,287],{},"try await servo.attach(pin: 9, minUs: 1000, maxUs: 2000)\n",[43,289,290],{"class":45,"line":70},[43,291,292],{},"try await servo.write(angle: 90)\n",[43,294,295],{"class":45,"line":76},[43,296,148],{"emptyLinePlaceholder":147},[43,298,299],{"class":45,"line":82},[43,300,301],{},"let neo = ConduytNeoPixel(device: device, moduleID: 1)\n",[43,303,304],{"class":45,"line":88},[43,305,306],{},"try await neo.begin(pin: 6, count: 64)\n",[43,308,309],{"class":45,"line":94},[43,310,311],{},"try await neo.fill(r: 0, g: 255, b: 0)\n",[43,313,314],{"class":45,"line":100},[43,315,316],{},"try await neo.show()\n",[14,318,319,320,323,324,323,327,323,330,323,333,323,336,323,339,342,343,347],{},"Available wrappers: ",[17,321,322],{},"ConduytServo",", ",[17,325,326],{},"ConduytNeoPixel",[17,328,329],{},"ConduytOLED",[17,331,332],{},"ConduytDHT",[17,334,335],{},"ConduytEncoder",[17,337,338],{},"ConduytStepper",[17,340,341],{},"ConduytPID",". See per-module pages under ",[344,345,254],"a",{"href":346},"\u002Fdocs\u002Fmodules\u002Fservo",".",[22,349,351],{"id":350},"errors","Errors",[14,353,354,355,32],{},"Every async device call throws ",[17,356,357],{},"ConduytDeviceError",[359,360,361,372,382,388],"ul",{},[362,363,364,367,368,371],"li",{},[17,365,366],{},".notConnected"," — call ",[17,369,370],{},"connect()"," first",[362,373,374,377,378,381],{},[17,375,376],{},".timeout(seq:)"," — no response within ",[17,379,380],{},"timeout"," (default 5s)",[362,383,384,387],{},[17,385,386],{},".nak(code:name:)"," — firmware returned NAK with an error code",[362,389,390,393],{},[17,391,392],{},".disconnected"," — transport closed mid-operation",[22,395,397],{"id":396},"transports","Transports",[399,400,401,417],"table",{},[402,403,404],"thead",{},[405,406,407,411,414],"tr",{},[408,409,410],"th",{},"Transport",[408,412,413],{},"Type",[408,415,416],{},"Notes",[418,419,420,434],"tbody",{},[405,421,422,426,431],{},[423,424,425],"td",{},"BLE",[423,427,428],{},[17,429,430],{},"BLETransport",[423,432,433],{},"CoreBluetooth-based, GATT service \u002F characteristics configured at init",[405,435,436,439,442],{},[423,437,438],{},"Serial",[423,440,441],{},"(BYO)",[423,443,444,445,448,449,452,453,456],{},"Implement ",[17,446,447],{},"ConduytTransport"," against ",[17,450,451],{},"IOKit"," or ",[17,454,455],{},"ORSSerialPort"," for macOS USB",[22,458,460],{"id":459},"concurrency","Concurrency",[14,462,463,466,467,470,471,474,475,478],{},[17,464,465],{},"ConduytDevice"," is ",[17,468,469],{},"actor","-style in spirit but currently uses an ",[17,472,473],{},"NSLock"," internally for the pending-continuations map. You can call methods from any task; sequence numbers are atomically allocated. For long-running listeners, store the device on ",[17,476,477],{},"@MainActor"," or another actor as appropriate for your app architecture.",[22,480,482],{"id":481},"versioning","Versioning",[14,484,485,486,489,490,347],{},"The package follows the protocol version. ",[17,487,488],{},"1.x"," requires firmware running protocol version 2 — exposed as ",[17,491,492],{},"ConduytProtocol.version",[494,495,496],"style",{},"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);}",{"title":39,"searchDepth":52,"depth":52,"links":498},[499,500,501,502,503,504,505],{"id":24,"depth":52,"text":25},{"id":131,"depth":52,"text":132},{"id":253,"depth":52,"text":254},{"id":350,"depth":52,"text":351},{"id":396,"depth":52,"text":397},{"id":459,"depth":52,"text":460},{"id":481,"depth":52,"text":482},"Swift Package Manager client for CONDUYT — async\u002Fawait, BLE-first, iOS + macOS.","md",{},"\u002Fdocs\u002Fsdks\u002Fswift",{"title":5,"description":506},"docs\u002Fsdks\u002Fswift","rSQ2vZeUpusWQSdCL6K1z4oLUT6O7L7LbDycvb5Ufq0",1777412315792]