Hikotest on iOS
Add the Swift package, connect it with two copy-paste values — no GitHub token — and call over-the-air business logic. Powered by the WasmKit runtime; pure Swift, no native dependencies.
What you'll need
| Platforms | iOS 15+ · macOS 12+ |
| Toolchain | Xcode 15 or newer (Swift 5.9 toolchain) |
| Package manager | Swift Package Manager |
| Runtime | WasmKit 0.1.5 — pure Swift WebAssembly runtime (resolved automatically) |
| Concurrency | async/await — initialization is an async throwing call |
| To connect | Your panel address + Project ID — copy them from Settings → SDK Integration. No GitHub token needed. |
1Add the package
In Xcode choose File → Add Package Dependencies… and enter the repository URL:
https://github.com/halil9393/HikotestIOSSDK.git
Or declare it in your own Package.swift:
dependencies: [
.package(url: "https://github.com/halil9393/HikotestIOSSDK.git", branch: "main")
],
targets: [
.target(
name: "YourApp",
dependencies: [.product(name: "HikotestSDK", package: "HikotestIOSSDK")]
)
]2Get your panel address and Project ID
In the panel, open your project and go to Settings → SDK Integration. You'll see two values with copy buttons:
| Panel address | The address of your Hikotest panel, e.g. https://your-panel.hikotest.app — this is panelBaseUrl |
| Project ID | A long unique id for your project (a UUID) — this is projectId |
3Connect and initialize at launch
Configure once — for example in your App struct or AppDelegate — then initialize. The SDK downloads (or loads the cached) release.wasm from the panel and starts its update loop.
import HikotestSDK
@main
struct YourApp: App {
init() {
Hikotest.shared.configure(HikotestConfig(
panelBaseUrl: "https://your-panel.hikotest.app", // from Settings → SDK Integration
projectId: "your-project-id" // from Settings → SDK Integration
))
}
var body: some Scene {
WindowGroup {
ContentView()
.task {
try? await Hikotest.shared.initialize()
}
}
}
}4Call your functions
The recommended path is the generated Swift wrapper. Every deploy writes sdk/swift/HikotestFunctions.swiftinto your project's release — parameter names, types and DocC comments included. Copy it into your app for compile-time-safe calls:
// Signatures and docs come from your panel deploy let price = try HikotestFunctions.applyCampaign(1000, "VIP30")
You can also call dynamically. Values travel through the type-safe HikoValue enum (.int / .float / .string / .boolean), with up to five named parameters per function:
let result = try Hikotest.shared.execute(
"applyCampaign",
signature: "(float,string)->float",
.float(1000), .string("VIP30")
)Hybrid mode — OTA lock (device-side guarantee)
Some functions (payments, pricing, authorization) should never change over-the-air. Download a release you trust from the panel (release.wasm + manifest.json), ship them as bundle resources and pass them at configure time:
Hikotest.shared.configure(HikotestConfig(
panelBaseUrl: "https://your-panel.hikotest.app",
projectId: "your-project-id",
localBundle: LocalBundle(wasmBytes: wasmBytes, manifestJson: manifestJson),
lockedFunctions: ["applyPayment"] // device-side lock list (optional)
))- A function runs from the embedded local bundle when the live manifest marks it ota:false (locked in the panel) or it is in your lockedFunctions set. Everything else keeps hot-reloading from the live OTA bundle.
- The device wins. The union is one-way: even if the panel unlocks a function remotely, anything in lockedFunctions keeps running from the embedded bundle until you ship an app update.
- A locked function missing from the embedded bundle throws HikotestError.otaLockedMissing — there is no silent OTA fallback.
- Fully offline mode: configure only localBundle (no panel, no repo) — the SDK never touches the network.
- Hikotest.shared.isLocallyPinned(_:) tells you where calls are served from.
How OTA updates behave
- Every deploy (and rollback) from the panel publishes an immutable release with a bumped bundle version (e.g. v1.0.7).
- A background task periodically asks the panel for the latest version; when a new one appears, the bundle is downloaded, cached and hot-loaded — no app restart, no App Store review.
- The last downloaded bundle is cached locally, so the app starts offline with the most recent logic.
- Wrapper code only changes when a function signature changes; internal logic updates arrive without touching your codebase.
Good to know
- The runtime is pure Swift (WasmKit) — nothing to notarize, no XCFramework binaries, and swift test style unit tests run on macOS without a simulator.
- The SDK mirrors the Android SDK API one-to-one, so cross-platform teams share the same mental model: configure → initialize → execute.
- "Missing export" on string functions means the bundle predates the current string ABI — redeploy the project from the panel.
Connect via GitHub token (legacy)
Older setup — read releases straight from GitHub— only if you were already using it
Before the panel path existed, the SDK read releases directly from your project's build repository on GitHub, which required a GitHub token. It still works, but the panel path above is preferred: no token, no rate-limit worries, nothing secret in your app. Use either the panel values or the GitHub values, never both.
Hikotest.shared.configure(HikotestConfig(
githubToken: Secrets.hikotestToken, // never hardcode
repoOwner: "your-github-username",
repoName: "your-project-build-repo"
))