[iOS] Fix MediaPicker FullPath for PHPicker results - #35805
Conversation
Materialize PHPicker results into managed temporary files before returning so FileResult.FullPath points to a readable path on iOS. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35805Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35805" |
|
/review -b feature/enhanced-reviewer |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
Clean up failed PHPicker loads, remove dead multi-select capture path, and keep processed file writes off the captured context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review -b feature/regression-check -p ios |
|
Reviewing test failures on this PR... Review PR Test Failures |
|
@stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu The PR has been updated and is ready for testing. Could you please try the artifacts from this PR and let us know whether it fixes the iOS MediaPicker FullPath regression for photos/videos in your apps? I manually verified the iOS video path scenario with a local test app using this branch: Artifact install instructions are in the PR description and the dogfood comment above. Thanks! |
|
/review -b feature/enhanced-reviewer -p ios |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the latest suggestions?
|
Hi @jfversluis, Apologies - I can't seem to run the script as I'm getting an error: curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35805 Should I try again later or try something else? It looks like there are build failures. Thanks. |
|
@craftylogic there are manual steps here as well: https://github.com/dotnet/maui/wiki/Testing-PR-Builds trying to figure out the script |
|
@jfversluis Thanks for the manual steps - I used the instructions to find the build artefacts at this address: Once I worked out how to get the nupkg files into my nuget.config LocalPackages I was able to force the downloaded Maui.Essentials library to be included. Based on this warning I assume my CSPROJ file changes allowed the local NUPKG to load:
With this release I can now confirm that my 'FullPath' issue is resolved as can be seen in this screen capture:
Thank you for all your efforts! |
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description Updates `eng/scripts/get-maui-pr.sh` and `eng/scripts/get-maui-pr.ps1` so users can still apply PR package artifacts when the aggregate `maui-pr` build is red because of unrelated CI legs, as long as the package-producing artifacts exist for the current PR commit. ### Changes - Treat a red aggregate `maui-pr` build as a warning instead of an immediate abort. - Keep `PackageArtifacts` as the hard gate before downloading/applying packages. - Filter AzDO fallback builds to the current PR head/merge context using `triggerInfo.pr.sourceSha`, `sourceVersion`, and the PR merge SHA. - Warn when `Pack macOS` or `Pack Windows` timeline records do not report success. - Update troubleshooting text to refer to completed `maui-pr` builds with `PackageArtifacts` rather than green checks. ### Validation - `bash -n eng/scripts/get-maui-pr.sh` - PowerShell parser validation for `eng/scripts/get-maui-pr.ps1` - `git diff --check` - Local throwaway MAUI projects under `/Volumes/NieuwVolume/maui-pr-artifact-verification-20260616101523`: - PR `#35805`: red aggregate build `1461390`, `PackageArtifacts` present, pack jobs succeeded; Bash and PowerShell scripts applied package `10.0.80-ci.pr35805.26312.37`; `dotnet restore` succeeded. - PR `#35923`: green aggregate build path applied package `10.0.80-ci.pr35923.26315.57`; `dotnet restore` succeeded. - PR `#35626`: missing `PackageArtifacts` failed before mutating the project. - PR `#999999`: nonexistent PR failed cleanly during PR lookup. - Wrong-SHA harness for PR `#35805`: refused to use older completed builds when none matched the requested head/merge commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
| // Create a temp file for the rotated image | ||
| var tempFileName = $"{Guid.NewGuid()}{Path.GetExtension(result.FileName)}"; | ||
| var tempFilePath = Path.Combine(Path.GetTempPath(), tempFileName); | ||
| var tempFilePath = PHPickerFileResult.CreateTemporaryFilePath(Path.GetExtension(result.FileName)); |
There was a problem hiding this comment.
🔍 AI-Generated Review (multi-model)
[moderate] Regression Prevention — tempFilePath is created inside the rotation try, so the catch cannot delete it if File.Create(tempFilePath) succeeds but rotatedStream.CopyToAsync(...) throws (for example on a low-storage device). That leaves a 0-byte/partial file in the maui-mediapicker temp directory until the 24-hour stale sweep; the same pattern appears in RotateImageFile at line 517. Hoist the temp path before the try and call PHPickerFileResult.TryDeleteTemporaryFile(tempFilePath) from the catch before falling back to the original result.
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@jfversluis — new AI review results are available based on this last commit:
8048cfd. To request a fresh review after new comments or commits, comment/review rerun.
🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix
Gate Result: ⚠️ INCONCLUSIVE
Platform: IOS
⚠️ verify-tests-fail.ps1exited before writing a verification report. Diagnostics below.
Exit code: 3
Likely cause:
- Test detection failed — no runnable tests were found in the PR diff.
Gate output log (last 60 lines)
📁 Output directory: CustomAgentLogsTmp/PRState/35805/PRAgent/gate/verify-tests-fail
🔍 Detecting base branch and merge point...
No PR detected, scanning remote branches for closest base...
✅ Base branch: main (via closest-merge-base)
✅ Merge base commit: fa1d0d2d
(1 commits ahead of main)
╔═══════════════════════════════════════════════════════════╗
║ FULL VERIFICATION MODE ║
╠═══════════════════════════════════════════════════════════╣
║ Fix files detected - will verify: ║
║ 1. Tests FAIL without fix ║
║ 2. Tests PASS with fix ║
╚═══════════════════════════════════════════════════════════╝
✅ Fix files (1):
- src/Essentials/src/MediaPicker/MediaPicker.ios.cs
🔍 Auto-detecting test filter from changed test files...
⚠️ No tests detected in this PR.
Searched for: UI tests, unit tests, XAML tests, device tests
Consider adding tests via write-tests-agent.
📱 UI Tests — Essentials
Detected UI test categories: Essentials
⏭️ Deep UI tests — 0 passed, 0 failed across 1 category on platform-pool agent (replaces in-process counts above). 1 category reported 0 tests.
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
Essentials |
0 tests | — |
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs) |
📋 Pre-Flight — Context & Validation
Issue: #32832 - MediaPicker.PickVideosAsync returns only file names as file path and doesn't compress the videos anymore under iOS
PR: #35805 - [iOS] Fix MediaPicker FullPath for PHPicker results
Platforms Affected: iOS, MacCatalyst
Files Changed: 1 implementation, 0 test
Key Findings
- The regression starts in .NET 10 preview 4+ for iOS PHPicker scenarios:
PickVideoAsync,PickVideosAsync, and commenters report photo variants returning only a filename/synthetic path instead of a readable filesystem path. - The PR's current fix materializes PHPicker results into MAUI-owned temp files, requests compatible representation for videos, skips image processing for non-images, adds temp cleanup/disposal, and removes the shared static picker reference.
- User artifact testing by
craftylogicreported the FullPath issue resolved with this PR's package. - GitHub CLI is unauthenticated in this environment, so pre-flight used local branch state and public GitHub API reads; required-check state remains undetermined here. The provided gate result is inconclusive and was not re-run.
Code Review Summary
Verdict: NEEDS_CHANGES
Confidence: low
Errors: 1 | Warnings: 1 | Suggestions: 1
Key code review findings:
- ✗ Missing regression coverage for the fixed PHPicker
FullPathcontract; no test files were added. - ⚠ Temp files can survive failed rotation writes in
src/Essentials/src/MediaPicker/MediaPicker.ios.cs:310-329and:517-531until stale cleanup. - ℹ Comment at
src/Essentials/src/MediaPicker/MediaPicker.ios.cs:393is stale/incorrect.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35805 | Materialize PHPicker results into MAUI-owned temp files with cleanup/disposal/lifecycle protections; request compatible video representation; image-process images only. | src/Essentials/src/MediaPicker/MediaPicker.ios.cs |
Original PR; code review found implementation direction sound but missing regression coverage. |
🔬 Code Review — Deep Analysis
Code Review — PR #35805
Independent Assessment
What this changes: iOS MediaPicker now materializes PHPicker results into MAUI-owned temp files, applies compatible video representation, and eagerly processes rotation/compression so FullPath points to readable files.
Inferred motivation: Fix PHPicker-backed FileResult.FullPath being a synthetic/non-readable path and reduce picker lifecycle races.
Reconciliation with PR Narrative
Author claims: Fixes iOS PHPicker FullPath, video compatibility, image-only processing, temp cleanup, static picker removal.
Agreement/disagreement: Matches the implementation. The main gap is regression coverage for the fixed FullPath contract.
Prior Review Reconciliation
| Prior ❌ Error Finding | Source | Status | Evidence |
|---|---|---|---|
Missing regression coverage for fixed FullPath contract |
MauiBot reviews on commit 8048cfd |
❌ Unresolved | Current diff changes only src/Essentials/src/MediaPicker/MediaPicker.ios.cs; no test files added. |
Blast Radius Assessment
- Runs for all instances: No — only iOS/MacCatalyst
MediaPickercalls. - Startup impact: No.
- Static/shared state: Reduced; removes static
PickerRef. New temp directory cleanup is shared but scoped tomaui-mediapicker.
CI Status
- Required-check result:
gh pr checks --requiredunavailable (ghunauthenticated). Public check-runs showmaui-pr/ Build Analysis failing. - Classification: likely PR-unrelated; failed Helix unit test is Windows
MauiAppBuild_BeginInvoke_DispatchesToDispatcher, while PR changes iOS MediaPicker only. - Action taken: invoked CI investigation path with public APIs; confidence capped low.
Findings
❌ Error — Missing regression coverage for fixed FullPath contract
The PR fixes a user-visible contract: PHPicker FileResult.FullPath should be a real readable file path. No regression test or device/UI coverage was added, and prior MauiBot ❌ findings for this remain unresolved. Per workflow rules, unresolved prior ❌ findings require NEEDS_CHANGES.
⚠️ Warning — Temp files can survive failed rotation writes
src/Essentials/src/MediaPicker/MediaPicker.ios.cs:310-329 and :517-531 create temp paths inside try blocks but do not delete the temp path if File.Create succeeds and CopyToAsync later throws. These are eventually swept by stale cleanup, but low-storage/write-failure paths can leak files for up to 24 hours.
💡 Suggestion — Incorrect comment
src/Essentials/src/MediaPicker/MediaPicker.ios.cs:393 says the method is only for iOS < 14, but the guard returns null for < 14 and proceeds on iOS 14+.
Failure-Mode Probing
- Swipe dismissal during async processing: completion paths null the presentation handler before explicit dismissal; swipe-dismiss still uses
TrySetResult, so double completion is benign. - Failed provider load: current code disposes the in-flight
PHPickerFileResultand accumulated results. - Non-image video processing: guarded by
IsImageFile, so resizing/rotation avoids videos.
Verdict: NEEDS_CHANGES
Confidence: low
Summary: Implementation direction looks sound and CI failure appears unrelated, but the unresolved prior ❌ test-coverage finding blocks LGTM under the skill rules. Add focused regression coverage or obtain explicit maintainer waiver.
🛠️ Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix-1 | Eagerly materialize PHPickerFileResult via LoadFileRepresentation before picker completion. |
✅ Build passed / ❌ self-review failed | 1 file | Minimal and likely fixes FullPath, but lacks single-flight concurrency, cancellation/disposal, and owned cleanup. |
| 2 | try-fix-2 | Prefer LoadInPlaceFileRepresentation provider URL, fallback to copy. |
✅ Build passed / ❌ self-review failed | 1 file | Avoids copies when possible, but in-place provider URLs are not durable enough for the FullPath contract after picker completion. |
| 3 | try-fix-3 | Persist the existing FileResult.OpenReadAsync stream into a temp file. |
✅ Build passed / ❌ self-review failed | 1 file | Restores a path through the existing abstraction, but keeps LoadDataRepresentation/NSData memory risk for large videos. |
| PR | PR #35805 | Copy LoadFileRepresentation output into MAUI-owned temp files with cleanup/disposal/lifecycle protections; request compatible video representation. |
1 file | Best implementation among explored options; still missing regression coverage per code review. |
Cross-Pollination
| Model/Reviewer | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 2 | No | NO NEW IDEAS: PhotoKit/assetIdentifier + PHAssetResourceManager/export is the remaining distinct avenue, but it is not likely better because it can require Photos-library authorization, fail for nil identifiers/iCloud/limited-library cases, complicate compatible-video export, and reintroduce representation/lifecycle variability. |
Exhausted: Yes
Selected Fix: PR #35805 — The PR's MAUI-owned temp-file approach is more robust than all alternatives generated here because it avoids LoadDataRepresentation memory pressure, avoids non-durable in-place URLs, and owns cleanup/disposal. It is not fully verified because the gate was inconclusive and no regression test exists.
🏁 Report — Final Recommendation
Comparative Report — PR #35805
Candidate ranking
| Rank | Candidate | Regression/build result | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
Best candidate. It keeps the PR's durable MAUI-owned temp-file implementation and applies the expert cleanup feedback for partially-created rotated temp files. | |
| 2 | pr |
Strongest submitted implementation. It restores FullPath using LoadFileRepresentation, avoids in-place URL lifetime issues, avoids LoadDataRepresentation video memory pressure, adds scoped temp ownership, and removes shared picker state. |
|
| 3 | try-fix-1 |
✅ iOS Essentials build passed; ❌ self-review failed | Likely fixes the visible FullPath symptom, but lacks the PR's single-flight load protection, cancellation/disposal handling, and scoped cleanup. |
| 4 | try-fix-3 |
✅ iOS Essentials build passed; ❌ self-review failed | Restores a path through OpenReadAsync, but keeps the LoadDataRepresentation/NSData path that can be unsafe for large videos. |
| 5 | try-fix-2 |
✅ iOS Essentials build passed; ❌ self-review failed | Provider in-place URLs are not durable enough for MAUI's FileResult.FullPath contract after picker completion, so this is the riskiest correctness model. |
No candidate had a confirmed failing regression test. The provided PR gate was inconclusive and Step 5a candidates only had local build/self-review evidence, so ranking is based on code correctness, lifecycle safety, and the known failure modes from expert review.
Winning candidate
Winner: pr-plus-reviewer
pr-plus-reviewer wins because it preserves the PR's MAUI-owned temp-file architecture while addressing the only actionable cleanup gap found during expert review. It is superior to all try-fix candidates because it avoids non-durable provider URLs, avoids loading large videos into memory, and includes lifecycle/concurrency protections around provider file materialization.
🧭 Next Steps — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
|
@craftylogic thank you soo much for testing it <3 |
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details Fixes #32832 `MediaPicker` on iOS 14+ uses `PHPickerViewController`. The PHPicker-backed `FileResult` was returning a synthetic filename for `FullPath` instead of a real filesystem path, which regressed direct file access patterns such as `File.Copy(result.FullPath, ...)`. Video picking also lost the old compatible representation behavior. ### Description of Change - Materializes PHPicker results into a MAUI-owned temporary folder before completing pick operations so `FileResult.FullPath` points to a readable file. - Requests compatible asset representation for videos only. - Keeps image rotation/resizing/compression on image files only, and ensures processed image results also expose real temp-backed `FullPath` values. - Adds cleanup for stale MediaPicker temporary files and explicit cleanup on dispose/error paths. - Removes the shared static picker reference to avoid overlapping picker lifecycle races. ### Testing - `dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimal` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=false` - `dotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=false` ### Artifact Testing Request @stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and `FullPath` access? --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
Fixes #32832
MediaPickeron iOS 14+ usesPHPickerViewController. The PHPicker-backedFileResultwas returning a synthetic filename forFullPathinstead of a real filesystem path, which regressed direct file access patterns such asFile.Copy(result.FullPath, ...). Video picking also lost the old compatible representation behavior.Description of Change
FileResult.FullPathpoints to a readable file.FullPathvalues.Testing
dotnet format src/Essentials/src/Essentials.csproj --no-restore --include src/Essentials/src/MediaPicker/MediaPicker.ios.cs --verbosity minimaldotnet build src/Essentials/src/Essentials.csproj -f net10.0-ios26.0 --no-restore /p:BuildIpa=false /p:EnableSourceLink=false /p:UseSharedCompilation=falsedotnet build src/Essentials/src/Essentials.csproj -f net10.0-maccatalyst26.0 --no-restore /p:EnableSourceLink=false /p:UseSharedCompilation=falseArtifact Testing Request
@stefanottauma @BohdanRomaniuk @craftylogic @marcojak @msoftie @DennisWelu if you are able, could you please try the artifacts from this PR and confirm whether they restore your iOS MediaPicker scenarios for photos/videos and
FullPathaccess?