Skip to content
Source
Sign inSign up

README.md

165 lines6.4 KB

1# T3 Code Mobile
2​
3> [!NOTE]
4> To install the released app from the App Store or Google Play, see [Mobile app](../../docs/user/install.md#mobile-app). This guide covers building it from source.
5​
6## Quickstart
7​
8> [!NOTE]
9> Uses native modules so using Expo Go is not supported. You need to use the Expo Dev Client.
10​
11This app has three variants:
12​
13- `development`: Expo dev client, installable side-by-side as `T3 Code Dev`
14- `preview`: persistent internal preview build, installable side-by-side as `T3 Code Preview`
15- `production`: store/release build as `T3 Code`
16​
17Run commands from `apps/mobile`.
18​
19T3 Connect is optional and disabled in a fresh clone. Public configuration belongs in the
20repository-root `.env` or `.env.local`, not an `apps/mobile/.env` file. See
21[`../../.env.example`](../../.env.example).
22​
23## Development
24​
25For simulator, emulator, or Android phone development, boot or connect a device, then install the
26native client that matches this checkout before starting Metro:
27​
28```bash
29vp run mobile:install ios [simulator-udid]
30# Or: vp run mobile:install android [emulator-or-phone-serial]
31vp run dev:client
32```
33​
34The device argument can be omitted when exactly one device is booted or connected. The helper
35compares this checkout's Expo fingerprint and the installed binary with its last install record,
36and reuses a matching client. Otherwise it installs the build for that fingerprint from
37`~/.cache/t3code/native-clients/artifacts`, then the shared task cache, and builds only when
38neither has it. A build runs in the `Mobile Dev Client` workflow (Blacksmith runners with warm
39Gradle and ccache state, and a macOS runner for iOS) when `gh` may dispatch workflows on
40`pingdotgg/t3code` and HEAD is pushed; the helper waits for the client in the shared cache.
41Otherwise, or when HEAD lacks your native edits or `T3_NATIVE_CLIENT_BUILD=local` is set, it builds
42on this machine. Main's client is built there on every native change, so most checkouts hit. One iOS simulator build serves every iPhone and iPad simulator, and one APK per
43ABI (x86_64 or arm64-v8a) serves every emulator and phone of that ABI. Build output goes to the
44log file it prints (`T3_NATIVE_CLIENT_VERBOSE=1` streams it instead). Builds are shared back when
45your task-cache login (`bash infra/task-cache/install.sh`) can write. `T3_NATIVE_CLIENT_CACHE=read`
46skips the upload and `off` skips the shared cache. Physical iPhones still use `vp run ios:dev`.
47​
48`--session <name>` installs into an agent-device session opened elsewhere, such as a device pool
49or a cloud simulator, instead of a local device: `vp run mobile:install android --session pool-1
50--metro http://<this-machine>:8081`. It uses only the cached build (x86_64 by default; `--abi`
51for ARM) and fails with the next step when no machine has built this fingerprint yet.
52​
53For a read-only decision, run `node ../../scripts/mobile-native-client.ts check <ios|android>
54[device]`: exit 0 means compatible, 2 means an install is needed, and 1 means an operational error.
55An externally installed client is unverified until the helper installs it once.
56​
57Start Metro for an already verified dev client:
58​
59```bash
60vp run dev:client
61```
62​
63Metro keeps its transform cache between ordinary starts. If the cache itself is causing stale or
64invalid output, clear it for one development-client start:
65​
66```bash
67vp run dev:client:reset
68```
69​
70Run that reset once after installing or changing the Uniwind dependency patch. Cached transforms
71can otherwise reference its previous pnpm package path. Ordinary Metro starts still keep the cache.
72​
73Component edits use Fast Refresh. See [mobile development lifecycle](../../docs/internals/mobile-development.md)
74before changing runtime ownership or refresh behavior.
75​
76Build and run the local iOS dev client:
77​
78```bash
79vp run ios:dev
80```
81​
82After changing a native dependency patch, rerun CocoaPods before rebuilding an existing iOS
83project. pnpm gives each patch hash a new package path; Pods can otherwise keep compiling the
84previous directory.
85​
86If your Xcode account only has a Personal Team, use a bundle identifier you control and opt into the
87reduced-capability local build. Personal Team builds omit the widget and share extensions, push
88entitlement, and native Sign in with Apple entitlement; builds without this opt-in are unchanged.
89​
90```bash
91T3CODE_IOS_PERSONAL_TEAM=1 \
92T3CODE_IOS_PERSONAL_TEAM_BUNDLE_ID=com.example.t3code.dev \
93vp run ios:dev
94```
95​
96Build and install a self-contained Release app that does not need Metro:
97​
98```bash
99vp run ios:release
100```
101​
102The Personal Team equivalent also needs a unique bundle identifier:
103​
104```bash
105T3CODE_IOS_PERSONAL_TEAM=1 \
106T3CODE_IOS_PERSONAL_TEAM_BUNDLE_ID=com.example.t3code \
107vp run ios:release
108```
109​
110Build and run the local iOS preview app:
111​
112```bash
113vp run ios:preview
114```
115​
116Inspect the resolved Expo config for a variant:
117​
118```bash
119vp run config:dev
120vp run config:preview
121```
122​
123Run static checks for mobile native code:
124​
125```bash
126node ../../scripts/mobile-native-static-check.ts
127```
128​
129The native lint task runs SwiftLint for Swift plus ktlint and detekt for Kotlin. Missing native tools are reported as warnings and skipped locally. CI installs the default toolset from `apps/mobile/Brewfile` before running the native checks.
130​
131## EAS Builds
132​
133Preview and production variants use Expo fingerprinting so OTA updates only reach binaries with matching native dependencies, config plugins, and patches. CI uses the `preview:dev` profile to reuse a compatible native build when possible.
134​
135The development variant uses `appVersion` to avoid recalculating the native fingerprint for each Metro launch manifest. `MOBILE_VERSION_POLICY` can override either default. If you distribute a custom Release build with the development identity and publish OTA updates to it, set `MOBILE_VERSION_POLICY=fingerprint` for both its build and updates. Changing the runtime policy requires a native rebuild for OTA matching; an existing dev client can still load local Metro bundles.
136​
137For preview or production EAS environments, set `T3CODE_CLERK_PUBLISHABLE_KEY`,
138`T3CODE_CLERK_JWT_TEMPLATE`, and `T3CODE_RELAY_URL`
139as EAS environment variables. Expo config maps the canonical values into the mobile build.
140​
141Create a PR preview dev-client build manually:
142​
143```bash
144vp run eas:ios:preview:dev
145```
146​
147Create a cloud dev-client build:
148​
149```bash
150vp run eas:ios:dev
151```
152​
153Create a persistent preview build:
154​
155```bash
156vp run eas:ios:preview
157```
158​
159Android equivalents:
160​
161```bash
162vp run eas:android:dev
163vp run eas:android:preview:dev
164vp run eas:android:preview
165```