跳到內容

iOS

本頁內容尚未翻譯。

Wails v3 applications run on iOS as native UIKit apps: a WKWebView renders the frontend, assets are served in-process over a custom wails:// URL scheme (no localhost server, no open ports), and the standard @wailsio/runtime works unchanged — service bindings, events, dialogs and the clipboard use the same /wails/runtime transport as on desktop.

The same main.go builds for desktop and iOS. iOS-specific behaviour is configured through application.Options.IOS, with per-platform Go files guarded by //go:build ios.

  • macOS with full Xcode installed (the command-line tools alone are not enough) — wails3 doctor shows the iOS SDKs it can find
  • Go 1.25+ and npm

From your project directory:

Terminal window
wails3 task ios:run

This generates the iOS scaffolding (build/ios/), compiles your Go code as a C archive (GOOS=ios), links it against UIKit, bundles, signs ad-hoc, boots a simulator if necessary, and launches the app.

Useful companions:

Terminal window
wails3 task ios:logs:dev # stream the app's logs from the simulator
wails3 task ios:xcode # open the generated Xcode project

In debug builds the webview is inspectable from Safari’s Develop menu.

Terminal window
wails3 task ios:package # production .app for the simulator
wails3 task ios:deploy-simulator # install + launch it

Production builds use -tags production,ios, are stripped, and compile out the framework’s internal diagnostics.

Terminal window
wails3 task ios:package IOS_PLATFORM=device \
CODESIGN_IDENTITY="Apple Development: You (TEAMID)" \
PROVISIONING_PROFILE=path/to/profile.mobileprovision
wails3 task ios:deploy-device [DEVICE_ID=<udid>] # via xcrun devicectl
wails3 task ios:package:ipa IOS_PLATFORM=device ... # distribution .ipa

IOS_PLATFORM=device selects the iphoneos SDK and the arm64-apple-ios<min> target. Entitlements from build/ios/entitlements.plist are applied to device builds only — get-task-allow by default; add capability keys as your app needs them.

build/config.yml:

ios:
bundleID: com.example.myapp
displayName: My App
version: 1.0.0
minIOSVersion: "15.0"

Application options (application.Options.IOS, applied at startup) include DisableScroll, DisableBounce, DisableScrollIndicators, DisableInputAccessoryView, EnableBackForwardNavigationGestures, DisableLinkPreview, EnableInlineMediaPlayback, EnableAutoplayWithoutUserAction, DisableInspectable, UserAgent, ApplicationNameForUserAgent, BackgroundColour, and native bottom tabs via EnableNativeTabs + NativeTabsItems.

Native device features — the IOS manager

Section titled “Native device features — the IOS manager”

iOS-specific native capabilities are exposed through the package-level application.IOS manager. You call it from Go, inside a //go:build ios file, so your shared code stays platform-agnostic (Android has the same shape via application.Android). This is the “manager pattern”: one singleton, flat method names, no per-feature objects to construct.

One-shot actions return immediately:

//go:build ios
application.IOS.Haptic("impact-medium") // impact-light|impact-medium|impact-heavy|success|warning|error|selection
application.IOS.Share(`{"text":"Hi","url":"https://wails.io"}`)
application.IOS.SetKeepAwake(true)
application.IOS.PostNotification(`{"title":"Done","body":"Build finished","delay":2}`)
application.IOS.SecureSet("token", "abc") // Keychain-backed

Query helpers return JSON strings — SafeAreaJSON(), AppInfoJSON(), PowerJSON(), NetworkJSON(), StorageJSON(), GetOrientation(), GetBrightness().

Asynchronous results: common:* and ios:* events

Section titled “Asynchronous results: common:* and ios:* events”

Anything that finishes later — a permission prompt, a sensor stream, a camera capture — delivers its result as a Wails event rather than a return value. Listen on either side of the bridge. Names use a common: prefix for capabilities shared with Android and an ios: prefix for iOS-only ones.

// Go
app.Event.On("common:location", func(e *application.CustomEvent) {
// e.Data -> {"lat":..,"lng":..,"accuracy":..} or {"error":..}
})
// frontend
import { Events } from "@wailsio/runtime";
Events.On("common:notification", (e) => { /* {ok, scheduled, presented, tapped, error} */ });
EventTriggered byPayload
common:biometricBiometricAuthenticate(reason){ok, error}
common:locationGetLocation(){lat, lng, accuracy} / {error}
common:motionSetMotion(true){x, y, z}
common:proximitySetProximity(true){near}
common:keyboardSetKeyboardWatch(true){visible, height}
common:torchSetTorch(bool){on, available}
common:notificationPostNotification(json){ok, scheduled, presented, tapped, error}
common:captureCapturePhoto() / CaptureVideo(){type, path, size, thumb}
common:screenCaptureSetScreenProtect(true){screenshot, recording}
ios:backgroundTaskBeginBackgroundTask(seconds){message, granted}

The kitchen-sink example under v3/examples/mobile wires every feature above end to end.

Beyond the compile-time application.Options.IOS flags, several WebView behaviours can be toggled at runtime from Go:

application.IOS.SetScrollEnabled(false)
application.IOS.SetBounceEnabled(false)
application.IOS.SetScrollIndicatorsEnabled(false)
application.IOS.SetBackForwardGesturesEnabled(true)
application.IOS.SetLinkPreviewEnabled(false)
application.IOS.SetInspectableEnabled(true)
application.IOS.SetCustomUserAgent("MyApp/1.0")

The bundled @wailsio/runtime also exposes a small frontend iOS namespace:

import { IOS } from "@wailsio/runtime";
await IOS.Haptics.Impact("medium"); // light|medium|heavy|soft|rigid
const info = await IOS.Device.Info();

Native bottom-tab selections arrive as a nativeTabSelected CustomEvent on window.

AreaStatus
WKWebView + in-process assets (wails://)
Service bindings, events (both directions)
Message dialogs✅ UIAlertController with button callbacks
Open file / files / directory dialogs✅ UIDocumentPicker (files imported as sandbox copies)
Save file dialogs❌ Returns an error — write inside the app sandbox instead
Clipboard✅ UIPasteboard
Screens API✅ UIScreen metrics incl. safe-area work area
Lifecycle events (events.IOS.*)
Window geometry, menus, system trayIntentional no-ops
Multiple windowsOnly the first window is displayed
  • Desktop code compiles unchanged under GOOS=ios; geometry/menu/tray calls become no-ops because iOS apps are fullscreen.
  • ios implies the darwin build tag: macOS-only files need //go:build darwin && !ios, and at runtime runtime.GOOS is "ios".
  • Replace save-file dialogs with writes into the app sandbox (for example the Documents directory) plus a share flow.
  • Design the frontend responsively; safe areas are handled natively.