iOS-App selbst bauen mit Xcode
Die iOS-App ist dasselbe Tauri-2-Projekt wie der Launcher auf dem PC, nur für iPhone und iPad gebaut. Diese Seite ist für alle, die mitentwickeln, und für Spieler, die die IPA lieber selbst bauen als unsere zu nehmen. Wenn du nur spielen willst, installier die offizielle App – siehe iPhone/iPad: mit AltStore/SideStore installieren.
- Du brauchst einen Mac mit Xcode. Das Xcode-Projekt lässt sich nur unter macOS erzeugen und liegt deshalb nicht im Repository – ein Skript legt es an.
- Zum Spielen braucht es die Spiel-Engine und JIT – genau wie bei der offiziellen App. Die Engine kommt in einem eigenen Schritt in die fertige App (siehe IPA bauen). Startest du die App direkt aus Xcode, fehlt die Engine: Alles andere geht, aber Spiele starten nicht.
- Apps, die mit einer kostenlosen Apple-ID signiert sind, öffnen sich nach 7 Tagen nicht mehr und müssen neu signiert (aufgefrischt) werden. Mit einer kostenlosen Apple-ID gehen nur 3 selbst installierte Apps gleichzeitig.
- Gebaut wird nur für echte Geräte (arm64) – einen Build für den iOS-Simulator gibt es nicht.
Die Befehle hier sind die, die das CI ausführt (.github/workflows/ci.yml Job launcher-ios, release.yml Jobs
iOS und iOS engine, .github/workflows/ios-engine.yml). Das CI signiert die App nie – es baut eine
unsignierte IPA, und AltStore/SideStore signieren sie beim Installieren mit der Apple-ID des Nutzers.
Was wo liegt
| Pfad | Was es ist |
|---|---|
scripts/ios-project.sh | Legt das Xcode-Projekt in src-tauri/gen/apple an (tauri ios init) und ergänzt Symbole und Info.plist-Einträge |
scripts/ios-unsigned-ipa.sh | Baut die Rust-Bibliothek, dann ein Xcode-Archiv ohne Code-Signatur, als IPA gezippt |
scripts/ios/build-engine.sh | Baut die Spiel-Engine (Amethyst-iOS an festem Commit, CMake, MobileGlues, Java-Teil) |
scripts/ios/package-ipa.sh | Legt die Engine in die App und signiert sie mit ldid und den Entitlements |
src-tauri/tauri.ios.conf.json | iOS-Abweichungen der Tauri-Konfiguration (iOS 15, kein Desktop-Updater) |
src-tauri/Info.ios.plist | Kamera-Text (QR-Code der PC-Fernbedienung) und Hintergrundabruf für Benachrichtigungen |
src-tauri/plugins/tauri-plugin-trs-game/ios/ | Swift-Teil, Quellen der Engine, trs-game.entitlements |
Voraussetzungen
| Werkzeug | Version / Hinweis |
|---|---|
| macOS mit Xcode | mit dem iPhoneOS-SDK. Eine Xcode-Version ist im Repository nicht festgelegt; das CI nimmt das Standard-Xcode der GitHub-Runner macos-latest (App) und macos-15 (Engine) |
| Homebrew | für xcodegen (installiert das Skript bei Bedarf selbst), ldid und cmake |
| Node.js und pnpm | Node 22, pnpm in der Version aus package.json (corepack enable) |
| Rust | stable über rustup, Target aarch64-apple-ios |
| JDK 8 | nur für die Engine (CI: Zulu 8). Es muss ein JDK 8 sein – build-engine.sh prüft das |
git, python3, zip | nutzen die Skripte |
Die App braucht iOS 15 (minimumSystemVersion in tauri.ios.conf.json). Das CI setzt für die App
IPHONEOS_DEPLOYMENT_TARGET=15.0, weil die Swift-Pakete der Plugins APIs ab iOS 14 nutzen; die Engine selbst wird für
14.0 gebaut.
IPA bauen
Code und Werkzeuge holen
git clone https://github.com/theredstonee/TRS-Launcher.git
cd TRS-Launcher
pnpm install
rustup target add aarch64-apple-ios
brew install ldid cmake
Oberfläche bauen
pnpm generate
Xcode-Projekt anlegen
bash scripts/ios-project.sh
Das Skript startet pnpm tauri ios init --ci, falls src-tauri/gen/apple noch fehlt, übernimmt Kamera-Text und
Hintergrundaufgabe aus src-tauri/Info.ios.plist in die Info.plist der App und legt die App-Symbole (dazu die
Event-Symbole als alternative Symbole) in den Asset-Katalog.
App ohne Signatur bauen
export IPHONEOS_DEPLOYMENT_TARGET=15.0
bash scripts/ios-unsigned-ipa.sh release build/TRS-Launcher-app.ipa
Was dabei passiert:
cargo build --lib --target aarch64-apple-ios --release --features tauri/custom-protocol, mitTAURI_CONFIG= Inhalt vontauri.ios.conf.json. Das Featurecustom-protocolbettet die Oberfläche ein – ohne sucht die App einen Entwicklungsserver auflocalhost:3000und schließt sich sofort wieder.- Die Bibliothek
libtrs_launcher_lib.awird nachsrc-tauri/gen/apple/Externals/arm64/release/libapp.akopiert. scripts/ios/disable-rust-phase.pyschaltet die Xcode-Build-Phase „Build Rust Code“ (tauri ios xcode-script) ab – sie funktioniert nur innerhalb eines laufendentauri ios build, und die Bibliothek liegt ja schon da.xcodebuild … archivemitCODE_SIGNING_ALLOWED=NO, danach wird die.appalsPayload/in die IPA gezippt.
Für einen Debug-Build nimmst du debug statt release (die Bibliothek landet dann in Externals/arm64/debug/). Für
CurseForge setzt du CURSEFORGE_API_KEY oder legst den Schlüssel in ~/.tauri/curseforge-api-key – freiwillig, ohne
ihn ist CurseForge ausgeblendet.
Spiel-Engine bauen
JAVA8_HOME=$(/usr/libexec/java_home -v 1.8) bash scripts/ios/build-engine.sh build/engine-ios
Das Skript holt Amethyst-iOS am festen Commit
9212a1894865e7ac0466029e25ddb0d895544c76, vergleicht die mitgelieferten Dateien damit, baut die native Engine und
MobileGlues mit CMake und den Java-Teil mit dem JDK 8. Heraus kommt ein Ordner mit Frameworks/, libs/,
resources/, LICENSES/ und engine.json. Die Java-Laufzeiten sind nicht dabei – die lädt die App beim ersten
Spielstart.
Engine in die App legen
bash scripts/ios/package-ipa.sh build/TRS-Launcher-app.ipa build/engine-ios build/TRS-Launcher.ipa
Das kopiert die Engine in die App, ergänzt die Info.plist-Einträge für die Dateien-App, das Querformat, Maus und
Controller und signiert alles mit ldid – die App mit den Entitlements aus
src-tauri/plugins/tauri-plugin-trs-game/ios/trs-game.entitlements (get-task-allow für JIT, das höhere
Speicherlimit und der große Adressraum). Eine andere Datei gibst du mit TRS_IOS_ENTITLEMENTS an.
Installieren
Kopier build/TRS-Launcher.ipa auf dein iPhone oder iPad und installier sie in AltStore oder SideStore über My Apps →
+. Sie signieren sie mit deiner Apple-ID, wie die offizielle App. Andere Werkzeuge, die eine IPA mit deiner Apple-ID
signieren, sollten auch gehen – getestet haben wir sie nicht. Zum Spielen dann JIT einschalten.
Aus Xcode mit eigener Apple-ID starten
Du kannst die App auch direkt aus Xcode auf einem angeschlossenen iPhone starten und mit deinem eigenen Team signieren (eine kostenlose Apple-ID geht als „Personal Team“). Das ist praktisch, wenn du an der Oberfläche arbeitest. Zwei Dinge dazu:
- Auf diesem Weg hat die App keine Spiel-Engine – beim Start einer Instanz meldet sie, dass die Engine fehlt. Anmeldung, Sozial, Garderobe, Modpacks und alles andere funktionieren.
- Das CI signiert nie mit einem Team – diesen Weg haben wir nicht getestet.
Rust-Bibliothek für Debug bauen
Mach die Schritte bis Xcode-Projekt anlegen, dann:
export IPHONEOS_DEPLOYMENT_TARGET=15.0
bash scripts/ios-unsigned-ipa.sh debug build/TRS-Launcher-debug.ipa
Danach liegt die Bibliothek in src-tauri/gen/apple/Externals/arm64/debug/libapp.a, und die Rust-Build-Phase im
Projekt ist abgeschaltet – Xcode kann die App also allein bauen.
Projekt öffnen
open src-tauri/gen/apple/*.xcodeproj
Wähle das Schema, das auf _iOS endet, und dein iPhone als Ziel.
Team und Bundle-ID setzen
Im App-Target unter Signing & Capabilities wählst du dein Team und änderst den Bundle Identifier in einen
eigenen (zum Beispiel io.github.deinname.trslauncher) – eine Bundle-ID kann bei Apple nur ein Team verwenden.
Starten
Drück Run. Ab iOS 16 fragt das iPhone zuerst nach dem Entwicklermodus (Einstellungen → Datenschutz & Sicherheit → Entwicklermodus). Mit einer kostenlosen Apple-ID musst du eventuell noch dein Entwicklerprofil unter Einstellungen → Allgemein → VPN und Geräteverwaltung als vertrauenswürdig markieren.
src-tauri/gen/apple und legst es neu an,
sind sie weg.Zu deiner eigenen App machen
- Bundle-ID: AltStore/SideStore signieren die IPA mit deiner Apple-ID – dafür musst du nichts ändern. Für Xcode änderst du die Bundle-ID dort (siehe oben).
identifierinsrc-tauri/tauri.conf.jsonnicht ändern. Er gilt auch für Android, wo das Kotlin-Paket und der Rust-Code daran hängen – der Android-Build bricht dann ab (siehe Android-App selbst bauen). Einidentifiernur für iOS intauri.ios.conf.jsonkönnte gehen, ist aber nicht getestet.- Die ID der Hintergrundaufgabe
dev.theredstonee.trslauncher.push-pollbleibt, wie sie ist: Sie steht sowohl insrc-tauri/Info.ios.plistals auch im Swift-Code des Push-Plugins, und iOS führt nur Aufgaben aus, die in der Info.plist stehen.
Was in deinem eigenen Build laut Code weiter funktioniert:
- Microsoft-Anmeldung läuft per Gerätecode (du tippst einen Code auf der Microsoft-Seite ein) – sie hängt nicht an der Bundle-ID.
- TRS-Dienste (Freunde, Chat, Umhänge, TRS-API) sprechen mit derselben API; App oder Signatur werden nicht geprüft.
- Links wie
trs-launcher://pack/<code>haben in jedem Build dasselbe Schema. - Updates: Dein Build hängt nicht an unserer AltStore-/SideStore-Quelle. Du aktualisierst ihn, indem du neu baust und installierst.
Wenn in deinem eigenen Build etwas nicht geht, melde es bitte.
Prüfungen ausführen
Dieselben Prüfungen wie im CI:
pnpm generate
cd src-tauri
IPHONEOS_DEPLOYMENT_TARGET=15.0 cargo clippy --workspace --target aarch64-apple-ios -- -D warnings
# Spiel-Plugin für iOS, Rust und sein Swift-Paket (Job „iOS engine“):
IPHONEOS_DEPLOYMENT_TARGET=14.0 cargo build -p tauri-plugin-trs-game --target aarch64-apple-ios
Probleme
„Build-Phase tauri ios xcode-script nicht gefunden“
scripts/ios-unsigned-ipa.sh schaltet diese Build-Phase beim ersten Lauf ab – ein zweiter Lauf findet sie nicht mehr
und bricht mit dieser Meldung ab. Das CI fängt immer mit einem frischen Projekt an. Lokal löschst du das erzeugte
Projekt und legst es neu an:
rm -rf src-tauri/gen/apple
bash scripts/ios-project.sh
Fehler zum Deployment Target oder zu iOS-14-APIs
Setz IPHONEOS_DEPLOYMENT_TARGET=15.0, bevor du die App baust (14.0 für die Prüfung des Engine-Plugins) – die
Swift-Pakete brauchen mindestens iOS 14.
Die App schließt sich gleich nach dem Öffnen
Wenn du die Rust-Bibliothek von Hand gebaut hast, fehlt wahrscheinlich --features tauri/custom-protocol – dann wartet
die App auf einen Entwicklungsserver auf localhost:3000. Nimm scripts/ios-unsigned-ipa.sh, das setzt es immer.
„JDK 8 fehlt (JAVA8_HOME setzen)“ oder „JAVA8_HOME ist kein JDK 8“
Der Java-Teil der Engine braucht genau ein JDK 8. Installier eins und lass JAVA8_HOME darauf zeigen.
„ldid fehlt (brew install ldid)“
package-ipa.sh signiert mit ldid: brew install ldid.
„vendored Datei weicht von Upstream ab“
Eine Datei unter ios/Engine/vendor/amethyst-ios weicht vom festen Amethyst-iOS-Commit ab. Abweichen dürfen nur die
gepatchten Dateien, die in UPSTREAM.md in diesem Ordner stehen – mach deine Änderung rückgängig oder pass die Liste an.
Das Spiel schließt sich gleich nach dem Start
Fast immer ist JIT nicht an. Siehe JIT einschalten. Das Log der
Engine findest du in der Dateien-App unter Auf meinem iPhone → TRS Launcher (trs-engine.log).
Minecraft 26.3 startet nicht
26.3 läuft auf iOS noch nicht (der Engine fehlt dort die SDL3-Anbindung). Nimm 26.2 oder älter.
„App kann nicht überprüft werden“ nach einer Woche
Die 7 Tage der kostenlosen Apple-ID sind um. Frisch die App in AltStore/SideStore auf oder starte sie noch einmal aus Xcode.
Lizenz und Name
Der TRS Launcher ist freie Software unter der GNU General Public License v3.0 (LICENSE, Urheberrechtshinweise in
NOTICE). Du darfst die App bauen, ändern und weitergeben. Gibst du eine IPA weiter, verlangt die GPL, dass das unter
derselben Lizenz passiert und du den vollständigen Quellcode genau dieses Builds samt deiner Änderungen zugänglich
machst. Die iOS-Engine basiert auf Amethyst-iOS (GPL-3.0) und bringt weitere fremde Teile mit; ihre Lizenztexte liegen
in der App (licenses/engine) und stehen in NOTICE – lass sie drin.
Eigene Markenregeln hat das Repository nicht. Trotzdem: Wenn du deinen Build weitergibst, gib ihm einen eigenen Namen und eine eigene Bundle-ID, damit ihn niemand für den offiziellen TRS Launcher hält, und verweise auf deinen Quellcode – nicht auf unseren Support.
Weiter geht's
Android-App selbst bauen
Die APK des TRS Launchers aus dem Quellcode bauen: Android-SDK und NDK, Rust-Targets, Debug- und Release-Build, eigener Signierschlüssel und eigene App-ID.
TRS Server Rules
Plugin und Server-Mod, mit dem du TRS-Client-Funktionen auf deinem Server sperrst, erzwingst oder begrenzt: Plattformen, Config, Protokoll und alle Modul-IDs.