# Asuka > 用 Go 开发应用,在 iOS、Android、macOS、Windows、Linux 和 Web 上使用各平台自己的控件(UIKit、Material 3、AppKit、Win32、GTK 4 与 libadwaita、DOM)。界面采用细粒度更新,保存即重载,每个平台都能直接打出发布构建。 Individual Markdown pages are listed below. All documentation is also available at https://asuka.egoist.dev/zh/llms-full.txt. ## Documentation - [Asuka 文档](https://asuka.egoist.dev/zh/docs.md): Asuka 让你用 Go 编写应用,并在 iOS、Android、macOS、Windows、Linux 和 Web 上以各平台的原生控件呈现。应用的界面就是一些返回视图的 Go 函数:Asuka 用各平台自己的控件把它们显示出来;某个 signal 变化时,只有读取了它的视图才会更新。 - [无障碍](https://asuka.egoist.dev/zh/docs/accessibility.md): Asuka 显示的是平台原生控件,所以屏幕阅读器、键盘操作和文字大小设置所需的大部分支持,不用写代码就已经具备了。本页介绍哪些是自动获得的,以及剩下的部分要用到的属性:标签、角色、分组、自定义操作、可调节视图、播报、键盘、文字大小和减弱动态效果,最后讲讲如何测试。 - [asuka.json](https://asuka.egoist.dev/zh/docs/asuka-json.md): asuka.json 放在应用目录下,用来告诉各个平台和应用商店它们需要知道的应用信息:名称和 ID、图标、应用能打开的链接和文件、签名用的密钥等。asuka dev、asuka build 和 asuka publish 都会读取它;其中 asuka dev 只在启动时读取一次,所以改动之后要停掉它再重新运行。 - [蓝牙](https://asuka.egoist.dev/zh/docs/bluetooth.md): asuka/sdk/bluetooth 用来和低功耗蓝牙(Bluetooth Low Energy)设备通信:心率带、体重秤、各类传感器、门锁,或者你自己做的开发板。它提供的能力和 react-native-ble-plx、Web Bluetooth 相当,并且在每个平台上都调用平台自己的 API:iOS 和 macOS 上是 Core Bluetooth;Android 上是 BluetoothLeScanner、BluetoothGatt 和 BluetoothGattServer;Windows 上是 Windows.Devices.Bluetooth;Linux 上通过 D-Bus 调用 BlueZ;浏览器里则是 Web Bluetooth(前提是浏览器支持)。 - [组件](https://asuka.egoist.dev/zh/docs/components.md): 组件就是一个返回 ui.Node 的 Go 函数。本页按用途分类介绍 ui 包提供的各种视图,以及与它配套、用于 Markdown 和 SVG 的几个包。只要平台自己有对应的控件,用的就是平台原生控件:iOS 上是 UIKit,Android 上是 Android Views 和 Material 3,macOS 上是 AppKit,Windows 上是绘制成 Windows 11(Fluent)风格的 Win32 控件,Linux 上是 GTK 4 和 libadwaita,浏览器里则是页面元素。视图如何确定尺寸和位置,请看布局;页面、标签页和弹出面板(sheet)请看导航。 - [核心概念](https://asuka.egoist.dev/zh/docs/concepts.md): 一个 Asuka 应用由两部分组成:只构建一次视图的 Go 函数,以及保存状态的 signal。本页介绍它们如何配合:根组件、signal 及其触发的更新、条件显示与列表渲染、owner 与清理、主线程,以及环境信息。 - [数据](https://asuka.egoist.dev/zh/docs/data.md): 应用的数据通常放在这几个地方:零散的小数据用 asuka/sdk/store,成批的记录用 asuka/sdk/sqlite 存进 SQLite,密钥和密码用 asuka/sdk/secure 放进平台的钥匙串,应用自己的文件则直接用 Go 的 os 读写。本页会逐一介绍它们,另外还会讲到如何通过 net/http 访问网络、如何监视文件变化,以及哪些调用可能会阻塞主线程。 - [桌面端](https://asuka.egoist.dev/zh/docs/desktop.md): 除了窗口和菜单栏(见导航),桌面端还有许多手机上没有的东西:托盘图标和程序坞(Dock)菜单、浮出面板、在后台常驻的应用、全局快捷键、面板与启动器、查找已安装的应用、鼠标穿透窗口、文件对话框与文件管理器、应用打开的文件、单实例、退出、最近使用的文档、基于文档的应用、登录时启动、自动更新、“正在播放”与媒体键、显示器、电源、应用图标上的进度,以及系统外观。如果想跟踪文件和文件夹的变化(比如应用正在展示的文件夹,或其他应用保存的文档),请参阅监视文件,这项功能在手机和 Web 上也有。 - [开发](https://asuka.egoist.dev/zh/docs/development.md): asuka dev 会运行你的应用,并在你保存时重新加载。它可以运行在 iOS 模拟器或 iPhone、Android 模拟器或手机、你的 Mac、PC 或 Linux 电脑上,也可以运行在浏览器里。本页介绍它在各个平台上是怎么做到的、重载时会保留什么,以及设备、资源和日志、哪些内容无法重载、asuka vet、你可能遇到的问题,还有 Asuka 自己的测试和基准测试。 - [设备与服务](https://asuka.egoist.dev/zh/docs/device.md): Asuka 提供了一系列包,让应用用上视图之外的设备能力:相机、条码、图像内容识别、照片和文件、文件预览、打印和 PDF、邮件和短信编辑界面、定位、通知和推送、声音、正在播放(Now Playing)和录音、网络状态、共享的媒体库、后台任务、接收其他应用的分享、JavaScript、登录和生物识别、屏幕、地图、应用商店提供的服务,以及崩溃报告。本页逐一介绍这些包:它们能做什么、API 怎么用、会给应用带来哪些权限,以及在各个平台上的表现。 - [快速上手](https://asuka.egoist.dev/zh/docs/getting-started.md): 使用 Asuka 需要先装好 Go,再为你要运行的每个平台准备好对应的工具。之后,一条命令就能创建应用,另一条命令就能运行它,并且每次保存都会自动重新加载。 - [多语言](https://asuka.egoist.dev/zh/docs/i18n.md): Asuka 应用会用用户的语言显示文案,并按照这种语言的阅读方向来布局。文案存放在目录(catalog)里,每种语言一个 JSON 文件;CLI 会根据这些文件生成一个 Go 包,为每条文案生成一个带类型的函数。 - [布局与样式](https://asuka.egoist.dev/zh/docs/layout.md): ui.Style 决定一个视图如何布局、长什么样。布局采用 CSS flexbox,单位是点(point);外观则包括颜色、圆角、边框、阴影和文字。本页会介绍这两部分,以及如何让样式随状态变化。布局在所有平台上都一样:Asuka 在 Go 里算好布局,再把平台的视图摆到对应的位置上。 - [动效与手势](https://asuka.egoist.dev/zh/docs/motion.md): 只要平台自带动画机制,Asuka 就直接用它:iOS 上是 UIView 动画,Android 上是 animator,macOS 上是 AppKit 的隐式动画和 Core Animation,浏览器里是 Web Animations API。Windows 和 GTK 没有针对视图 frame(位置与尺寸)的动画,所以 Windows 和 Linux 宿主会自己逐帧推进,用的也是同样的曲线。你只要在 ui.Animate 里修改状态,这次修改在屏幕上引起的移动就会以动画呈现。本页依次介绍:为变化添加动画、进入与退出过渡、共享元素、逐帧动画、触摸/鼠标/触控板手势、触感反馈,以及减弱动态效果。 - [Asuka 与 MyGo](https://asuka.egoist.dev/zh/docs/mygo.md): MyGo 是一个用 Go 开发桌面应用的框架,对手机的支持即将推出。两者都只用 Go,调用桌面系统时也都不需要 cgo。它们的区别在于应用能运行在哪里,更重要的是由谁来呈现界面:MyGo 自己绘制界面,或者显示一个网页;Asuka 则直接使用平台原生控件。 - [原生代码](https://asuka.egoist.dev/zh/docs/native.md): Asuka 没有封装的功能,应用可以通过原生包来使用。原生包是一个 Go 包,在 Go 里声明一个模块(一个接口)或一个视图(它的属性),再由每个平台用自己的语言实现:iOS 和 macOS 上用 Swift,Android 上用 Kotlin,Web 上用 JavaScript,Windows 和 Linux 上用 Go。asuka native generate 会为每一端生成带类型的胶水代码。在 Go 里,调用模块的方法就像调用任何 Go 接口一样,显示视图也和显示任何组件一样。值以紧凑的二进制格式在两端之间传递,不经过 JSON,也不用反射。 - [导航](https://asuka.egoist.dev/zh/docs/navigation.md): 一个应用的骨架由这几样东西搭成:页面组成的导航栈、标签页、弹出面板(sheet)、警告框和菜单;到了桌面端,还有窗口和菜单栏。它们用的都是各平台自己的实现: - [NFC 标签](https://asuka.egoist.dev/zh/docs/nfc.md): asuka/sdk/nfc 用来读写 NFC 标签:标签上的 NDEF 消息(链接、文本、应用自己的数据)、标签本身(ID 和技术类型),以及发给标签的原始命令。它做的事和 react-native-nfc-manager、Web NFC 一样,只是在每个平台上都用平台自己的 API:iOS 上是带系统面板的 Core NFC,Android 上是读卡器模式(reader mode),Web 上是 Chrome for Android 的 Web NFC。Mac、PC 和 Linux 会如实回答它们没有 NFC。 - [Asuka 与 SwiftUI、Expo 的功能对照](https://asuka.egoist.dev/zh/docs/parity.md): 下面每一行都是应用经常需要的一项功能,分别列出 SwiftUI 和 Expo 的做法,以及 Asuka 提供的对应能力。除非该行另有说明,✓ 表示 Asuka 支持的所有平台(iOS、Android、Mac、Windows、Linux 和 Web)都能用;如果某个平台本身不具备某项能力(比如 Mac 没有传感器,浏览器没有主屏幕小组件),对应的包会如实告诉调用方不支持。至于浏览器做不到手机能做的事时各个包会如何替代,见 Web。 - [插件](https://asuka.egoist.dev/zh/docs/plugins.md): 插件是一个自带库的 Go 包:这些库用 C、Zig 或 Rust 编写,已经为每个平台预先构建好,插件的 Go 代码不借助 cgo 就能调用它们。使用插件只需导入它,命令行工具会在每个平台上把它的库和应用一起打包发布。asuka/sdk/sqlite 就是一个插件(见数据)。 - [应用内购买](https://asuka.egoist.dev/zh/docs/purchases.md): asuka/sdk/purchase 通过各平台自己的应用商店,在应用里售卖商品:消耗型商品(金币、提示)、非消耗型商品(一个关卡、永久的“Pro”)、自动续期的订阅,以及不自动续期的订阅。它覆盖了 react-native-iap、expo-iap 和 RevenueCat 的 SDK 在设备端提供的能力,用的都是各商店当前的 API: - [打包与发布](https://asuka.egoist.dev/zh/docs/shipping.md): asuka build 会在应用目录(或你指定的目录)下,为某个平台制作发布构建,输出到该目录的 dist 中。asuka publish 则负责上传:把 iOS 和 Android 构建传到各自的应用商店,也就是 TestFlight 和 App 审核,或者 Google Play 的某个轨道(见发布到应用商店);把桌面构建的已签名更新传到 GitHub Releases 或 S3 存储桶,已安装的应用会从那里自动更新(见自动更新)。 - [测试](https://asuka.egoist.dev/zh/docs/testing.md): 应用的界面就是一些 Go 函数,所以可以直接用 go test 来测试。uitest 包会在没有设备、没有窗口、也没有显示器的情况下挂载你的组件,然后像用户一样,根据屏幕上显示的内容去操作它们。 - [Web](https://asuka.egoist.dev/zh/docs/web.md): 同一个应用也能在浏览器里运行:Go 代码编译成 WebAssembly,视图就是页面的 DOM。Web 和 iOS、Android、Mac、Windows、Linux 一样,是 Asuka 支持的平台之一,用的是同一份 Go 代码。核心创建的每个视图都对应一个元素,摆放在核心布局算出的位置上,原生宿主摆放自己的控件也是这样做的。因此布局用的是 Asuka 自己的实现(用 Go 写的 flexbox 和 grid),在每个平台上都一致;叶子节点则由真实的元素来测量,和原生宿主测量自己的控件一样。控件直接用浏览器自带的(