Mobile Experimental/iOS Parity
Use this skill when src/mobile-experimental must match src/mobile/ios feature-wise while keeping Avalonia, MAUI, Android, and iOS platform heads idiomatic.
Feature parity means the same user outcome, compatible persisted data, comparable error handling, and platform-native presentation. It does not mean copying SwiftUI into Avalonia/MAUI or forcing identical visual chrome.
Non-negotiables
- Treat
src/mobile/ios as the behavioral contract.
- Keep experimental code native to its stack:
- Avalonia:
.axaml, compiled bindings, avares:// assets, platform services from TopLevel, Android/iOS platform heads where needed.
- MAUI: XAML pages, Shell navigation,
FilePicker, Launcher, platform heads where needed.
- Android platform heads: intents, content URI handling, scoped cache files, Android package metadata.
- iOS platform heads: bundle IDs, URL schemes, share extension/app-group behavior, iOS appearance defaults.
- Preserve cross-platform file/data contracts:
.sxcu, .xsdc, upload queue/history records, destination IDs, generated URLs, and user-facing import messages where practical.
- Do not let experimental convenience drift from production identity. App IDs, URL schemes, document types, app group IDs, logo, version display, and About links should match
src/mobile/ios unless intentionally forked.
- Use the Avalonia docs MCP rules at the start of Avalonia work. Avoid WPF-only patterns such as triggers,
pack:// URIs, and DependencyProperty.
First pass
- Read
AGENTS.md, this skill, and .ai/skills/mobile-android-ios-parity/SKILL.md for shared parity lessons.
- Inspect:
src/mobile/ios/README.md
src/mobile/ios/XerahSMobile
src/mobile/ios/ShareExtension
src/mobile-experimental/XerahS.Mobile.Ava
src/mobile-experimental/XerahS.Mobile.Maui
src/mobile-experimental/XerahS.Mobile.Core
src/mobile-experimental/XerahS.Mobile.iOS.ShareExtension
- Create a focused parity matrix before coding:
| Behavior | iOS source | Experimental source | Status | Native implementation plan |
| --- | --- | --- | --- | --- |
| About screen metadata and links | ... | ... | missing/partial/done | ... |
Keep rows observable. Avoid documenting unrelated implementation details.
Default parity checklist
- App identity: bundle/application IDs, URL scheme, app group, display name, version/build, logo.
- Launch/loading flow and top-level navigation.
- Share receive/open-in-place for one and multiple files.
- Accepted input types: images, video, audio, PDFs, text, arbitrary files, URLs,
.sxcu, .xsdc.
- Cache copies preserve useful file names and extensions and avoid overwrites.
.sxcu import updates or adds custom uploaders and navigates/statuses like iOS.
.xsdc import supports encrypted S3 destination configs or clearly preserves the pending passphrase flow.
- Remote
.sxcu deep link: xerahs://import-sxcu?url=....
- Upload queue, progress, result URL/error display, copy actions, and persisted history.
- S3 options: region, endpoint, path-style/custom domain, signed payload, public ACL.
- Custom uploader options: method, headers, parameters, body, arguments, URL/deletion/thumbnail/error extraction.
- HEIC/HEIF conversion with native platform APIs or documented unsupported behavior.
- Settings validation and list/detail navigation.
- About screen metadata, links, social links, and logo.
- Native feel: Android Material-like touch sizes/system bars; iOS Cupertino-like typography, spacing, tint, navigation behavior.
Implementation rules
- Prefer shared C# behavior in
XerahS.Mobile.Core only when both Avalonia and MAUI need the same domain logic.
- Keep UI in each app's native UI layer:
- Avalonia views in
XerahS.Mobile.Ava/Views, view models in XerahS.Mobile.Ava/ViewModels, platform APIs in Platforms/*.
- MAUI pages in
XerahS.Mobile.Maui/Views, view models in XerahS.Mobile.Maui/ViewModels, platform APIs in Platforms/*.
- Do not put Avalonia or MAUI types into
XerahS.Mobile.Core.
- For Avalonia resources, use
avares://XerahS.Mobile.Ava/... and ensure assets are AvaloniaResource.
- For Avalonia URL opening, prefer
TopLevel.GetTopLevel(control)?.Launcher.LaunchUriAsync(uri) from view code-behind when the launcher is inherently UI/platform-bound.
- For Android share/open flows, avoid shell-only
file:// assumptions; real parity needs content:// handling from Files/share sheet.
- For app identity, match production iOS:
- App/bundle ID:
com.xerahs.xerahs.mobile
- Share extension ID:
com.xerahs.xerahs.mobile.ShareExtension
- App group:
group.com.xerahs.xerahs
- URL scheme:
xerahs
Build workflow
For Android build/deploy details, use .ai/skills/build-android/SKILL.md.
Common commands from src/mobile-experimental:
dotnet build XerahS.Mobile.Core/XerahS.Mobile.Core.csproj
dotnet build XerahS.Mobile.Ava/XerahS.Mobile.Ava.csproj -f net10.0-android
dotnet build XerahS.Mobile.Maui/XerahS.Mobile.Maui.csproj -f net10.0-android
Before push, also follow root AGENTS.md build integrity rules. Do not disable warnings-as-errors.
Commit workflow
Commit each completed parity slice before starting unrelated work when the tree is committable.
Good slice boundaries:
- Skill/docs for experimental parity workflow.
- App identity and platform metadata.
- About screen parity.
.sxcu/.xsdc import behavior.
- Share/open/deep-link intent routing.
- Native-feel UI polish.
Use the root version prefix from Directory.Build.props and AGENTS.md, for example [vX.Y.Z] [Feature] Add experimental mobile About parity.
QA workflow
- For Android experimental apps, use
Test Android Apps: android-emulator-qa.
- Build/install the exact app head being tested.
- Launch by resolved package/activity, not stale old IDs.
- Derive tap coordinates from the UI tree, not screenshots.
- Verify About metadata, share/import status messages, Settings navigation, and History behavior with UI tree summaries where possible.
- If emulator validation is limited by content URI grants, local cleartext HTTP, missing iOS signing, or platform workload constraints, state the limitation exactly.
Lessons learned
- Experimental contains both Avalonia and MAUI heads. If a change is user-facing and both heads expose the same feature, update both or explicitly document why one head is out of scope.
- App identity drifts easily in experimental projects. Always check
.csproj, Android manifest/activity, iOS Info.plist, entitlements, and share extension IDs together.
- Do not claim
.sxcu/.xsdc parity just because upload accepts arbitrary files. Config imports must be classified before upload queueing.
- MAUI and Avalonia can share import/domain code in
XerahS.Mobile.Core, but each app should keep native navigation and launcher behavior in its own UI layer.
- Remove debug-only labels or deployment IDs from mobile UI before calling it native-feeling.
Reporting
Final responses for this workflow should include:
- The iOS behavior contract used.
- Experimental heads changed: Avalonia, MAUI, shared core, platform heads.
- Build/test commands run.
- Emulator/device QA performed.
- Remaining parity gaps or platform limitations.
1---2name: mobile-experimental-ios-parity3description: Compare or implement experimental MAUI/Avalonia mobile parity with src/mobile/ios. Excludes native Android.4---56# Mobile Experimental/iOS Parity78Use this skill when `src/mobile-experimental` must match `src/mobile/ios` feature-wise while keeping Avalonia, MAUI, Android, and iOS platform heads idiomatic.910Feature parity means the same user outcome, compatible persisted data, comparable error handling, and platform-native presentation. It does not mean copying SwiftUI into Avalonia/MAUI or forcing identical visual chrome.1112## Non-negotiables1314- Treat `src/mobile/ios` as the behavioral contract.15- Keep experimental code native to its stack:16 - Avalonia: `.axaml`, compiled bindings, `avares://` assets, platform services from `TopLevel`, Android/iOS platform heads where needed.17 - MAUI: XAML pages, Shell navigation, `FilePicker`, `Launcher`, platform heads where needed.18 - Android platform heads: intents, content URI handling, scoped cache files, Android package metadata.19 - iOS platform heads: bundle IDs, URL schemes, share extension/app-group behavior, iOS appearance defaults.20- Preserve cross-platform file/data contracts: `.sxcu`, `.xsdc`, upload queue/history records, destination IDs, generated URLs, and user-facing import messages where practical.21- Do not let experimental convenience drift from production identity. App IDs, URL schemes, document types, app group IDs, logo, version display, and About links should match `src/mobile/ios` unless intentionally forked.22- Use the Avalonia docs MCP rules at the start of Avalonia work. Avoid WPF-only patterns such as triggers, `pack://` URIs, and `DependencyProperty`.2324## First pass25261. Read `AGENTS.md`, this skill, and `.ai/skills/mobile-android-ios-parity/SKILL.md` for shared parity lessons.272. Inspect:28 - `src/mobile/ios/README.md`29 - `src/mobile/ios/XerahSMobile`30 - `src/mobile/ios/ShareExtension`31 - `src/mobile-experimental/XerahS.Mobile.Ava`32 - `src/mobile-experimental/XerahS.Mobile.Maui`33 - `src/mobile-experimental/XerahS.Mobile.Core`34 - `src/mobile-experimental/XerahS.Mobile.iOS.ShareExtension`353. Create a focused parity matrix before coding:3637```markdown38| Behavior | iOS source | Experimental source | Status | Native implementation plan |39| --- | --- | --- | --- | --- |40| About screen metadata and links | ... | ... | missing/partial/done | ... |41```4243Keep rows observable. Avoid documenting unrelated implementation details.4445## Default parity checklist4647- App identity: bundle/application IDs, URL scheme, app group, display name, version/build, logo.48- Launch/loading flow and top-level navigation.49- Share receive/open-in-place for one and multiple files.50- Accepted input types: images, video, audio, PDFs, text, arbitrary files, URLs, `.sxcu`, `.xsdc`.51- Cache copies preserve useful file names and extensions and avoid overwrites.52- `.sxcu` import updates or adds custom uploaders and navigates/statuses like iOS.53- `.xsdc` import supports encrypted S3 destination configs or clearly preserves the pending passphrase flow.54- Remote `.sxcu` deep link: `xerahs://import-sxcu?url=...`.55- Upload queue, progress, result URL/error display, copy actions, and persisted history.56- S3 options: region, endpoint, path-style/custom domain, signed payload, public ACL.57- Custom uploader options: method, headers, parameters, body, arguments, URL/deletion/thumbnail/error extraction.58- HEIC/HEIF conversion with native platform APIs or documented unsupported behavior.59- Settings validation and list/detail navigation.60- About screen metadata, links, social links, and logo.61- Native feel: Android Material-like touch sizes/system bars; iOS Cupertino-like typography, spacing, tint, navigation behavior.6263## Implementation rules6465- Prefer shared C# behavior in `XerahS.Mobile.Core` only when both Avalonia and MAUI need the same domain logic.66- Keep UI in each app's native UI layer:67 - Avalonia views in `XerahS.Mobile.Ava/Views`, view models in `XerahS.Mobile.Ava/ViewModels`, platform APIs in `Platforms/*`.68 - MAUI pages in `XerahS.Mobile.Maui/Views`, view models in `XerahS.Mobile.Maui/ViewModels`, platform APIs in `Platforms/*`.69- Do not put Avalonia or MAUI types into `XerahS.Mobile.Core`.70- For Avalonia resources, use `avares://XerahS.Mobile.Ava/...` and ensure assets are `AvaloniaResource`.71- For Avalonia URL opening, prefer `TopLevel.GetTopLevel(control)?.Launcher.LaunchUriAsync(uri)` from view code-behind when the launcher is inherently UI/platform-bound.72- For Android share/open flows, avoid shell-only `file://` assumptions; real parity needs `content://` handling from Files/share sheet.73- For app identity, match production iOS:74 - App/bundle ID: `com.xerahs.xerahs.mobile`75 - Share extension ID: `com.xerahs.xerahs.mobile.ShareExtension`76 - App group: `group.com.xerahs.xerahs`77 - URL scheme: `xerahs`7879## Build workflow8081For Android build/deploy details, use `.ai/skills/build-android/SKILL.md`.8283Common commands from `src/mobile-experimental`:8485```bash86dotnet build XerahS.Mobile.Core/XerahS.Mobile.Core.csproj87dotnet build XerahS.Mobile.Ava/XerahS.Mobile.Ava.csproj -f net10.0-android88dotnet build XerahS.Mobile.Maui/XerahS.Mobile.Maui.csproj -f net10.0-android89```9091Before push, also follow root `AGENTS.md` build integrity rules. Do not disable warnings-as-errors.9293## Commit workflow9495Commit each completed parity slice before starting unrelated work when the tree is committable.9697Good slice boundaries:9899- Skill/docs for experimental parity workflow.100- App identity and platform metadata.101- About screen parity.102- `.sxcu`/`.xsdc` import behavior.103- Share/open/deep-link intent routing.104- Native-feel UI polish.105106Use the root version prefix from `Directory.Build.props` and `AGENTS.md`, for example `[vX.Y.Z] [Feature] Add experimental mobile About parity`.107108## QA workflow109110- For Android experimental apps, use `Test Android Apps: android-emulator-qa`.111- Build/install the exact app head being tested.112- Launch by resolved package/activity, not stale old IDs.113- Derive tap coordinates from the UI tree, not screenshots.114- Verify About metadata, share/import status messages, Settings navigation, and History behavior with UI tree summaries where possible.115- If emulator validation is limited by content URI grants, local cleartext HTTP, missing iOS signing, or platform workload constraints, state the limitation exactly.116117## Lessons learned118119- Experimental contains both Avalonia and MAUI heads. If a change is user-facing and both heads expose the same feature, update both or explicitly document why one head is out of scope.120- App identity drifts easily in experimental projects. Always check `.csproj`, Android manifest/activity, iOS `Info.plist`, entitlements, and share extension IDs together.121- Do not claim `.sxcu`/`.xsdc` parity just because upload accepts arbitrary files. Config imports must be classified before upload queueing.122- MAUI and Avalonia can share import/domain code in `XerahS.Mobile.Core`, but each app should keep native navigation and launcher behavior in its own UI layer.123- Remove debug-only labels or deployment IDs from mobile UI before calling it native-feeling.124125## Reporting126127Final responses for this workflow should include:128129- The iOS behavior contract used.130- Experimental heads changed: Avalonia, MAUI, shared core, platform heads.131- Build/test commands run.132- Emulator/device QA performed.133- Remaining parity gaps or platform limitations.