Skip to content

Removed PhotosAddOnly permission request within MediaPicker.ios#34287

Merged
kubaflo merged 1 commit intodotnet:inflight/currentfrom
Kyranio:net10-34246
Mar 22, 2026
Merged

Removed PhotosAddOnly permission request within MediaPicker.ios#34287
kubaflo merged 1 commit intodotnet:inflight/currentfrom
Kyranio:net10-34246

Conversation

@Kyranio
Copy link
Copy Markdown

@Kyranio Kyranio commented Feb 27, 2026

Description of Change

Removed permission request for adding photos to the devices library on iOS, inside MediaPicker.ios, which doesn't need this permission at this spot inside the code as it does not add the newly captured photo to the device's library here.

Given the official documentation, adding the picture to the device's library is an action given in the example after the CapturePhotoAsync is called, if the task's result contains a value.
This action is completely optional, the developer could implement different logic for handling the picture data after calling CapturePhotoAsync, meaning the permission request becomes unnecessary and redundant.

It is up to the developer to save the image to the device, which then requires the permission, meaning the developer should implement the permission request within their own logic.

Issues Fixed

Fixes #34246
Fixes #34661

Permission request for adding photos to device library in MediaPicker.ios
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34287

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34287"

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Feb 27, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@Kyranio! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@jfversluis
Copy link
Copy Markdown
Member

It is up to the developer to save the image to the device, which then requires the permission, meaning the developer should implement the permission request within their own logic.

While that might be true, doesn't our implementation always save it to the gallery on iOS? We don't have an option to set the right now (see #30439), so because of that, we also need to have this permission now. If we make that optional for .NET 11, then we can make this permission optional as well

@Kyranio
Copy link
Copy Markdown
Author

Kyranio commented Mar 2, 2026

While that might be true, doesn't our implementation always save it to the gallery on iOS?

If that is the case, then this might actually be a bug instead, as a photo taken with iOS (handled with MediaPicker) does in fact not save it to the gallery. The source code of the MediaPicker PhotoAsync method itself does not contain any logic indicating that the image is to be saved to the device itself, nor to it's gallery... which was why I initially posted the issue #34246 (under a different account, related to the company I work for) and created this pullrequest.

It's also why I referenced the official documentation which contains a code-snippet, suggesting that a developer needs to save the image to the device after calling CapturePhotoAsync themselves, in their own code. This in itself led me to believe that requesting the permission shouldn't be within the PhotoAsync method but rather within the user's own code.

If the PhotoAsync task should save the picture to the device's gallery regardless, the documentation would probably need to be updated. The PhotoAsync method might need to be looked at, however, as in our experience it does not add the pictures to the gallery by itself...
But maybe the MediaPicker isn't implemented correctly in our own code; we are all human too after all!

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Mar 22, 2026

🤖 AI Summary

📊 Expand Full Review95870d0 · Removed:
🔍 Pre-Flight — Context & Validation

Issue: #34246 - iOS MediaPicker CapturePhotoAsync without "PhotosAddOnly" permission
PR: #34287 - Removed PhotosAddOnly permission request within MediaPicker.ios
Platforms Affected: iOS only
Files Changed: 1 implementation (src/Essentials/src/MediaPicker/MediaPicker.ios.cs), 0 test

Key Findings

  • The PR removes 5 lines from MediaPicker.ios.cs that called await Permissions.EnsureGrantedAsync<Permissions.PhotosAddOnly>() before entering the UIImagePickerController capture branch.
  • The removed block only ran when pickExisting == false (i.e., capturing a new photo/video with the camera).
  • No tests were added or modified in the PR. No unit tests, device tests, or UI tests cover this specific permission flow.
  • The linked issue argues that PhotosAddOnly guards a non-existent gallery-write operation. The iOS UIImagePickerController.Camera flow captures an image, passes it to the delegate as a FileResult, and never calls UIImageWriteToSavedPhotosAlbum or PHPhotoLibrary APIs.
  • A maintainer (jfversluis) raised a concern: does the MAUI implementation already save to the gallery, making PhotosAddOnly necessary? After code-tracing, that concern is unfounded — no gallery-save call exists in the path. Issue Implement SaveToGallery property for MediaPicker #30439 is a feature request to add SaveToGallery, not a description of current behavior.
  • The permission removal was confirmed correct by two independent human reviews (kubaflo) and three AI model analyses posted in the PR comments.
  • PR was merged on 2026-03-22 by kubaflo.
  • Prior agent review found (MauiBot, 2026-03-22): Recommended REQUEST CHANGES due to missing tests and platform mismatch. That recommendation was overridden by maintainer code review evidence.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34287 Remove the PhotosAddOnly permission request before UIImagePickerController camera flow ❌ Gate FAILED src/Essentials/src/MediaPicker/MediaPicker.ios.cs Original PR; merged

🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Add SaveToGallery opt-in to MediaPickerOptions; condition PhotosAddOnly request on it ⚠️ Blocked 2 files + PublicAPI entries Adds public API; simpler removal is better since MAUI never saves to gallery
2 try-fix Check NSPhotoLibraryAddUsageDescription in Info.plist at runtime; skip permission if key absent ⚠️ Blocked 1 file Technically sound but adds complexity for a path that shouldn't need the permission at all
3 try-fix AppContext switch Microsoft.Maui.MediaPicker.RequestPhotoAddPermission to gate legacy behavior ⚠️ Blocked 1 file Adds maintenance burden for a regression fix that needs no opt-out
4 try-fix Remove permission + add explanatory comment documenting why ⚠️ Blocked 1 file Close to PR but with documentation value; marginally better but comment not strictly necessary
PR PR #34287 Remove PhotosAddOnly permission request from iOS capture path ❌ Gate FAILED 1 file Original PR — merged; simplest and correct

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 No All approaches are variations on unconditional vs conditional removal; PR's unconditional removal is correct
gpt-5.3-codex 2 Yes (flawed) Suggested fail-open + fallback on photo-library write error — assessed as technically flawed since UIImagePickerController.Camera never writes to gallery, so no error to catch
claude-sonnet-4.6 2 No PR's removal is provably correct; all alternatives add unnecessary complexity

Exhausted: Yes
Selected Fix: PR #34287 — The simple 5-line removal is the most correct and minimal fix. All 3 alternative approaches (SaveToGallery property, plist check, AppContext switch) add complexity around a permission that guards no actual operation. The gpt-5.3-codex cross-pollination idea was technically flawed. The fix was merged after extensive maintainer code review confirming UIImagePickerController.Camera never calls PHPhotoLibrary or any gallery-write API.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE 1 iOS implementation file changed; 0 tests added
Gate ❌ FAILED Tests did not behave as expected — no validating tests exist in the PR
Try-Fix ✅ COMPLETE 4 attempts (all Blocked — iOS unavailable on Android agent); PR's fix selected as best
Report ✅ COMPLETE

Summary

PR #34287 removes an unnecessary Permissions.PhotosAddOnly request from the iOS UIImagePickerController camera capture path in MediaPicker.ios.cs. The change is logically correct and was confirmed by two independent human reviews and three AI analyses before merge. The gate failed because the PR includes no automated tests and the requested review platform (Android) cannot exercise this iOS-only behavior. All 4 alternative fix approaches explored via try-fix were either more complex than needed (adding SaveToGallery API, plist check, AppContext switch) or equivalent to the PR's fix (removal + comment). The PR's simple removal is the best implementation — but the absence of test coverage is a real gap.

Root Cause

The PhotosAddOnly permission request was erroneously introduced during the MediaPicker iOS modernization (PR #28920). The UIImagePickerController.Camera delegate in MAUI extracts captured media via DictionaryToMediaFile and returns a FileResult — it never calls UIImageWriteToSavedPhotosAlbum, PHPhotoLibrary.PerformChanges, or any photo-library write API. The permission was guarding a non-existent gallery-save operation, requiring apps to declare NSPhotoLibraryAddUsageDescription in their Info.plist even when they only needed camera access.

Fix Quality

The PR's fix (5-line removal) is the strongest of all explored candidates:

  • Correct: Confirmed by code tracing — no gallery-write call exists in the capture path
  • Minimal: Single file, 5 lines removed, no new API surface
  • Merged: Maintainer kubaflo confirmed the fix after independent code review
  • Gap: No automated test coverage validating the permission behavior before/after the change — the only testing is manual verification on iOS

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Mar 22, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Mar 22, 2026

Independent Code Review

I traced the full iOS capture flow end-to-end to verify whether this PR is correct or should be closed.

Finding: The PR is valid and should be merged (not closed)

The PhotosAddOnly permission request guards a non-existent operation. Here is the evidence:

  1. No gallery-save API exists anywhere in the MediaPicker path. I searched the entire src/Essentials/src/ tree for UIImageWriteToSavedPhotosAlbum, PHPhotoLibrary.performChanges, creationRequestForAsset, or any other photo-library write zero matches in MediaPicker code. The only PHPhotoLibrary references are in Permissions.ios.tvos.macos.cs for checking/requesting authorization status.call

DictionaryToMediaFile, which extracts the image URL or UIImage from the picker info dictionary and wraps it in a FileResult. No gallery write happens.

  1. UIImagePickerController with SourceType.Camera does NOT auto-save to the photo this is standard iOS behavior. The captured image is delivered via the delegate callback only. To persist to the camera roll, the app must explicitly call UIImageWriteToSavedPhotosAlbum or use PHPhotoLibrary neither of which MAUI does.APIs library

  2. This was a regression introduced by PR Modernize MediaPicker iOS #28920 ("Modernize MediaPicker iOS"). Before that refactoring, there was no PhotosAddOnly request in the capture path. PR Modernize MediaPicker iOS #28920 added it during modernization without a corresponding gallery-save operation, making it an unnecessary addition.

Addressing @jfversluis's concern

doesn't our implementation always save it to the gallery on iOS?

the code does not save to the gallery. Issue #30439 ("Implement SaveToGallery property for MediaPicker") is a feature request to add that capability, not a description of current behavior. The issue's description ("By default, the MediaPicker now saves images to the gallery") likely refers to Android's behavior or is aspirational; the iOS implementation has no such logic.No

Recommendation

This PR correctly removes an unnecessary permission request that forces apps to declare NSPhotoLibraryAddUsageDescription even when they never write to the photo library. The change is a single-line removal with clear justification. Merging it would unblock users who only need camera capture without gallery access (as reported in #34246).

The concern about test coverage from the bot review is understandable, but this is a permission-check the behavior of the capture flow itself is unchanged. The risk is minimal.removal

@kubaflo kubaflo changed the base branch from main to inflight/current March 22, 2026 13:34
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Mar 22, 2026

We ran this PR through three independent AI models for a second opinion. Each was given the full code context, the maintainer concern, and the issue history.


Verdict Merge:

  • Traced the full iOS capture flow end-to-end. Zero gallery-write APIs (UIImageWriteToSavedPhotosAlbum, PHPhotoLibrary.performChanges, creationRequestForAsset) found anywhere in MediaPicker code.
  • UIImagePickerController with SourceType.Camera does NOT auto-save to the camera standard iOS behavior.roll
  • The PhotosAddOnly request was a regression introduced by PR Modernize MediaPicker iOS #28920 (MediaPicker modernization) without a corresponding gallery-save operation.
  • The maintainer concern about implicit gallery-saving is issue Implement SaveToGallery property for MediaPicker #30439 is a feature request to add that capability, not a description of current behavior.unfounded

Verdict Merge:

  • Confirmed zero calls to UIImageWriteToSavedPhotosAlbum, PHPhotoLibrary.PerformChanges, or any photo-library write API in the MediaPicker path.
  • The delegate extracts the captured image from the info dictionary and wraps it in a no Photo Library interaction occurs.CompressedUIImageFileResult
  • Risk is "extremely low." The only theoretical edge case is developers relying on MAUI to pre-request a permission they later need for their own save logic, which is bad practice.
  • Blocking on test coverage is testing system permission dialogs and camera UI requires specialized infrastructure.impractical

Verdict Merge:

  • The removal is there is no code path that writes to the photo library, making PhotosAddOnly objectively unused.justified
  • The maintainer's "implicit save to gallery" concern is "very likely UIImagePickerController camera capture does not magically become a library-write.incorrect"
  • Suggests optionally adding an inline comment explaining that callers who want gallery-save should request PhotosAddOnly themselves.
  • Blocking the bugfix on tests is unnecessary since it's a straightforward removal of an unused permission request.

Model Merge? Maintainer concern valid? Risk level
Claude Opus 4.6 no save-to-gallery code exists Minimal No Yes
Gemini 3 Pro UIImagePickerController does not auto-save Extremely low No Yes
GPT-5.2 no code path writes to photo library Low No Yes

Unanimous agreement across all three models: The PhotosAddOnly permission guards a non-existent operation and was erroneously introduced in PR #28920. This PR correctly removes it.

@kubaflo kubaflo merged commit 4c07ec9 into dotnet:inflight/current Mar 22, 2026
3 of 4 checks passed
@Kyranio Kyranio deleted the net10-34246 branch March 23, 2026 08:00
PureWeen pushed a commit that referenced this pull request Mar 24, 2026
### Description of Change

Removed permission request for adding photos to the devices library on
iOS, inside MediaPicker.ios, which doesn't need this permission at this
spot inside the code as it does not add the newly captured photo to the
device's library here.

Given the [official
documentation](https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/device-media/picker?view=net-maui-10.0&tabs=windows#take-a-photo),
adding the picture to the device's library is an action given in the
example _after_ the CapturePhotoAsync is called, if the task's result
contains a value.
This action is completely optional, the developer could implement
different logic for handling the picture data after calling
CapturePhotoAsync, meaning the permission request becomes unnecessary
and redundant.

It is up to the developer to save the image to the device, which then
requires the permission, meaning the developer should implement the
permission request within their own logic.

### Issues Fixed

Fixes #34246
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Mar 27, 2026

🚦 Gate — Test Verification

📊 Expand Full Gate95870d0 · Removed:

Gate Result: ❌ FAILED

Platform: android


KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 30, 2026
…et#34287)

### Description of Change

Removed permission request for adding photos to the devices library on
iOS, inside MediaPicker.ios, which doesn't need this permission at this
spot inside the code as it does not add the newly captured photo to the
device's library here.

Given the [official
documentation](https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/device-media/picker?view=net-maui-10.0&tabs=windows#take-a-photo),
adding the picture to the device's library is an action given in the
example _after_ the CapturePhotoAsync is called, if the task's result
contains a value.
This action is completely optional, the developer could implement
different logic for handling the picture data after calling
CapturePhotoAsync, meaning the permission request becomes unnecessary
and redundant.

It is up to the developer to save the image to the device, which then
requires the permission, meaning the developer should implement the
permission request within their own logic.

### Issues Fixed

Fixes dotnet#34246
sheiksyedm pushed a commit that referenced this pull request Apr 4, 2026
### Description of Change

Removed permission request for adding photos to the devices library on
iOS, inside MediaPicker.ios, which doesn't need this permission at this
spot inside the code as it does not add the newly captured photo to the
device's library here.

Given the [official
documentation](https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/device-media/picker?view=net-maui-10.0&tabs=windows#take-a-photo),
adding the picture to the device's library is an action given in the
example _after_ the CapturePhotoAsync is called, if the task's result
contains a value.
This action is completely optional, the developer could implement
different logic for handling the picture data after calling
CapturePhotoAsync, meaning the permission request becomes unnecessary
and redundant.

It is up to the developer to save the image to the device, which then
requires the permission, meaning the developer should implement the
permission request within their own logic.

### Issues Fixed

Fixes #34246
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community ✨ Community Contribution s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS MediaPicker CapturePhotoAsync without "PhotosAddOnly" permission

4 participants