Skip to content

Fix ios appstore bundle - #1

Merged
pythonpoet merged 3 commits into
pythonpoet:mainfrom
mirkobozzetto:fix-ios-appstore-bundle
Aug 26, 2026
Merged

pythonpoet merged 3 commits into
pythonpoet:mainfrom
mirkobozzetto:fix-ios-appstore-bundle

Conversation

@pythonpoet

Copy link
Copy Markdown
Owner

Adds the keys Apple Transporter / altool validation has required since
iOS 14 / 2024 App Store rules:

- ITSAppUsesNonExemptEncryption=false default (skips per-upload export
  compliance prompt; apps using non-exempt crypto can override via
  Dioxus.toml `[ios.plist]`).
- Modern `UILaunchScreen` dict replaces `UILaunchStoryboardName`. Apple
  rejects iPad-supporting bundles that reference a missing storyboard;
  the dict requires no storyboard file (iOS 14+).
- `CFBundleSupportedPlatforms` reduced to a single `iPhoneOS` value.
  Apple rejects `[iPhoneOS, iPadOS]` — iPadOS is not a valid platform
  identifier here, the binary is iPhoneOS regardless of device family.
- Placeholders for `DT*` / `MinimumOSVersion` / `CFBundlePackageType`
  metadata wired into the template via handlebars guards; the Rust side
  populates them in the next commit.

Part of the fix for DioxusLabs#3817.
Adds a small `IosDtMetadata` struct and `collect_ios_dt_metadata` helper
that probes the local SDK / Xcode install (`xcrun --sdk iphoneos
--show-sdk-version`, `defaults read .../DTXcode`, `sw_vers
-buildVersion`) and feeds the values into the handlebars iOS Info.plist
template.

Apple Transporter / altool reject App Store IPAs that omit
`DTPlatformName`, `DTPlatformVersion`, `DTSDKName`, `DTSDKBuild`,
`DTXcode`, `DTXcodeBuild`, `DTCompiler`, `DTPlatformBuild`,
`BuildMachineOSBuild`, `MinimumOSVersion`, or `CFBundlePackageType` —
the same set Xcode injects when it builds an iOS app.

Each probe is best-effort: a failure leaves the field empty and the
template's `{{#if}}` guards drop the key, so non-developer machines
still produce a valid `.app` (just not one App Store will accept).
`MinimumOSVersion` is sourced from `Dioxus.toml`'s
`[ios].deployment_target` (defaults to `15.0`).

Part of the fix for DioxusLabs#3817.
…DioxusLabs#3817)

Adds an opt-in `--appstore` flag to `dx bundle --platform=ios` that
completes the chain Apple App Store / Transporter / altool require for
upload. Default behavior (dev signing) is unchanged.

When `--appstore` is set:

- `auto_provision_signing_name` looks for an "Apple Distribution"
  identity instead of "Apple Development".
- `auto_provision_entitlements` filters provisioning profile candidates
  to those without a `ProvisionedDevices` key (= App Store distribution
  profiles, not dev / ad-hoc).
- Generated entitlements use `get-task-allow=false` (Apple ITMS rejects
  App Store uploads where the key is `true`).
- `should_codesign` is forced on so `dx bundle` produces a signed `.app`
  even without an explicit `--codesign` flag.

Regardless of `--appstore`, iOS bundles are now App Store-shaped:

- Nested `.appex` extensions under `PlugIns/` are signed inside-out with
  their own provisioning profiles (matched by each extension's
  CFBundleIdentifier). Apple rejects bundles whose nested extensions
  ship unsigned or with stale dev certs.
- `AppIcon.xcassets` at the crate root is compiled via `xcrun actool`
  and the resulting CFBundleIcons keys are merged into the main
  Info.plist. Apple rejects iOS bundles missing the 120x120 icon.
- `ios/PrivacyInfo.xcprivacy`, if present at the crate root, is copied
  into the bundle. Apple has required PrivacyInfo on App Store
  submissions since 2024.
- Widget / extension Info.plists are patched with the same DT*
  metadata, version strings (CFBundleVersion + CFBundleShortVersionString
  parity), `LSRequiresIPhoneOS`, `CFBundleSupportedPlatforms`, and
  `UIRequiredDeviceCapabilities` the main bundle carries.

End-to-end verified against a real iOS app (FlowFlow) using
`xcrun altool --validate-app -f <ipa> -t ios`: Apple responds
`VERIFY SUCCEEDED with no errors`.

All bundle-content modifications happen before any `codesign` call so
the signature covers the final bundle contents.

Closes DioxusLabs#3817.
@pythonpoet
pythonpoet merged commit f08a06e into pythonpoet:main Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants