# Go + Swift in AT-IRC PoC, 2026-10-30. ## Result Possible. `gomobile bind` (`golang.org/x/mobile`) emits a static `AtircGo.xcframework` linked into the app. No dynamic library, no embedding; App Store-safe. ## Setup - Install both tools: `go install golang.org/x/mobile/cmd/{gomobile,gobind}@latest`. `bind` shells out to `gobind`; installing only `gomobile` fails with "gobind was not found". - `GoLib/go.mod`: `module atirc/golib`; requires `golang.org/x/mobile/bind`. - `GoLib/golib.go`: exported `Version`, `Echo`, `SHA256Hex`, `ParseCommand`, `Counter`. - Build: `gomobile bind -target=ios,iossimulator -o GoLib/AtircGo.xcframework atirc/golib`. ## Bridging - `string` <-> `NSString`; `[]byte` <-> `NSData` (byte slices are mutable, passed by reference). - Exported struct -> ObjC class (`GolibCounter`), methods/properties bound. - `(T, error)` -> `NSError**`; Swift sees an explicit `NSErrorPointer`, not `throws`. Max two results; second must be `error`. - Calls are synchronous; goroutines work. ## Type limits (gobind docs) - Supported: signed ints, floats, `string`, `bool`, `[]byte`, functions, interfaces, structs with supported exported fields/methods. - Unsupported: other slices, maps, channels, generics; docs list signed ints only. - A panic crossing the boundary exits the process. - Proxy reference cycles leak. - Go can also call ObjC directly via reverse bindings (`import "ObjC/Foundation/NSDate"`). ## Xcode - Per-SDK `FRAMEWORK_SEARCH_PATHS` must point at the slice, not the xcframework parent: `.../AtircGo.xcframework/ios-arm64` (device) and `.../ios-arm64_x86_64-simulator` (sim). - `OTHER_LDFLAGS = $(inherited) -framework AtircGo`. Static framework: nothing to embed. - `UpdateTargetBuildSetting` rejects `[sdk=...]` keys; set them in `project.xcproj` JSON. ## Validated (iPhone, iOS 27.2) - Tests pass: strings, `[]byte` <-> `Data`, struct + methods, `(T, error)` -> `NSError`, goroutines, Go -> Swift callbacks. - Interface collides with generated class, so Swift sees `GolibCallbackProtocol`. - Callbacks arrive on a Go thread; hop to `MainActor` before touching UI. ## Size (Release, arm64) - Wrapper unreferenced: 0 delta (dead-stripped). - Wrapper referenced (force-loaded): 1.1 MB -> 3.1 MB binary (+2.0 MB); Go `__text` +768 KB. ## Rebuild - `GoLib/build.sh`; `GoLib/AtircGo.xcframework` is gitignored. ## Caveats - iOS sandbox: no `os/exec`/fork; networking OK. - Device slice ~5.2 MB unstripped; app stripping applies. - Regenerate after Go changes (candidate Run Script phase; script sandboxing is ON).