-
Notifications
You must be signed in to change notification settings - Fork 8
Native iOS
FEBuilderGBA has an experimental native iOS / iPadOS port built on the cross-platform Avalonia GUI — the iOS counterpart of the Native Android head. It is a real .ipa that runs the shared Avalonia UI on-device, reusing the same platform-agnostic seams the Android port introduced.
Authoritative reference: the full design and status lives in the in-repo
docs/IOS.md. This page is a summary.
- A
FEBuilderGBA.iOS/application head (AppDelegate : AvaloniaAppDelegate<App>) that builds and packages an.ipaconsuming the same Avalonia views as the desktop GUI. - The shared
FEBuilderGBA.Avaloniaproject multi-targetsnet9.0;net9.0-ios. - Built on top of
FEBuilderGBA.Core(platform-independent) +FEBuilderGBA.Avalonia(shared UI). WinForms is not iOS-capable and is excluded.
The iOS target framework is opt-in and OFF by default, so the desktop solution and all desktop CI keep seeing net9.0 only and are completely untouched (mirrors Android's EnableAndroidTarget):
dotnet workload install ios
dotnet build FEBuilderGBA.iOS/FEBuilderGBA.iOS.csproj -c Release -p:EnableIosTarget=trueThe -p:EnableIosTarget=true global property is required so NuGet restore cross-targets the shared project too. iOS builds require macOS + Xcode (currently Xcode 26.5, provided by the macos-26 runner in CI). The iOS head is deliberately excluded from FEBuilderGBA.sln — the required desktop build check runs the whole solution on a Windows runner with no iOS workload, so adding the head to the .sln would break unrelated PRs.
| Area | How it works |
|---|---|
config/ bundling |
The config/ tree ships as a BundleResource (with LogicalName preserving the config/<subpath> structure) and is version-stamped, extracted on first run into an app-private writable dir (Library/febuildergba), via the pure, desktop-unit-tested AndroidConfigExtractorCore + DirectoryAssetSource. The iOS bundle is read-only, so config must live in a writable location. |
| ROM file I/O |
Stream-based via Avalonia IStorageProvider — the same seam the Android port added for SAF — so security-scoped iOS document picks work without a plain file path. |
| Navigation | Reuses the Android single-view shell (INavigationService + page/view-stack host) under ISingleViewApplicationLifetime; no iOS-specific UI code was needed. |
| SkiaSharp pin |
SkiaSharp.NativeAssets.iOS is pinned to 2.88.9 to match Avalonia's bundled native Skia — a 3.x managed package against an 88.x native crashes inside the Avalonia process. |
| Runtime viability | iOS Release is full AOT + trimmed, and the Core/ROM pipeline is reflection-heavy, so the head enables the Mono interpreter (UseInterpreter=true) and links only the SDK (MtouchLink=SdkOnly) to maximize the chance the shipped .ipa actually runs. |
The CI/release .ipa is unsigned (there is no Apple Developer signing on this project), so it is NOT directly installable on a stock device. To run it you must re-sign it with your own Apple ID using a sideloading tool:
- AltStore or Sideloadly (re-sign with your Apple ID), or Apple Configurator.
- Download
FEBuilderGBA-ios-unsigned-ipa.zipfrom the latest release (attached when the macOS build succeeds — it is a soft/advisory asset), unzip to get the.ipa, then sideload it.
When a maintainer adds the APPLE_* GitHub Actions secrets, CI switches to a release-signed build (see docs/IOS.md §6).
-
ios.yml— advisory (non-required, macOS runner) build that produces the unsigned.ipaand verifies the bundledconfig/tree survived. Cannot block PR merges. -
release.yml— a softiosjob (continue-on-error, not in the mandatory verify-assets list) attachesFEBuilderGBA-ios-unsigned-ipa.zipto aver_*release when the build succeeds, and degrades to "release without iOS" if it doesn't.
The honest status: the .ipa builds and its config bundling is verified in CI, but the on-device runtime is not yet validated:
- Touch interaction, file pickers, and reaching/using every editor are unproven on a real device (iOS AOT/trim adds a runtime dimension Android's Mono JIT does not).
- The ~24 per-editor
OperatingSystem.IsAndroid()file-flow guards in the shared UI are not yet extended to iOS (build-safe; they take the untested desktop path at runtime) — a documented follow-up. - Like Android,
config/patch2(binary-patch library) and the FE-Repo graphics/music resources are not bundled (large git-delivered payloads).
See docs/IOS.md for the layer-by-layer detail and build prerequisites.
-
docs/IOS.md— authoritative, full detail - Native Android — the sibling mobile head (shares all the runtime seams)
- Avalonia GUI — the shared cross-platform frontend the iOS head consumes
- Getting Started — platforms & downloads
- Reporting Bugs — including the iOS preview feedback discussion