Fix media silently not saving to Photos (Save to Camera Roll)#2186
Open
estevecastells wants to merge 1 commit into
Open
Fix media silently not saving to Photos (Save to Camera Roll)#2186estevecastells wants to merge 1 commit into
estevecastells wants to merge 1 commit into
Conversation
When saving a photo/video from a chat to the iOS photo library, the save
could intermittently "glitch" and never appear in Photos. The authorized
save closure swallowed every failure on the way to PHPhotoLibrary:
- A failed AVAssetExportSession in the motion-photo path hit
`guard success else { return }` and never called putCompletion(), so the
signal hung forever and nothing was saved.
- `addAssetIdentifierToJPEG(...)!` force-unwrapped, crashing on any image
the re-encode could not handle.
- The completion handler always reported success even when the change
block staged nothing or PhotoKit returned an error, so a failed save was
indistinguishable from a successful one.
- Videos were always copied to a hardcoded ".mp4" temp path, discarding the
source container's real extension.
Make the path honest and resilient:
- Preserve the source file's extension for the temp copy.
- Replace the force-unwrap with a guard.
- On export failure or a failed paired (motion-photo) write, fall back to
saving the plain still image so it still lands, and always finish the
signal so the progress HUD dismisses.
- Track whether a resource was actually staged and log when media did not
land, instead of reporting an unconditional success.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Saving media to the iOS Photo Library can silently fail — the save appears to complete (progress HUD dismisses as if successful) but the photo/video never lands in Photos. This has been reproducible for a long time and is very annoying in daily use (high impact: it's the core "Save to Camera Roll" action).
The root cause is that the authorized save closure in
submodules/SaveToCameraRoll/Sources/SaveToCameraRoll.swiftswallows every failure on the way toPHPhotoLibrary:AVAssetExportSessionhitsguard success else { return }and never callsputCompletion(), so the signal hangs forever and nothing is written.addAssetIdentifierToJPEG(imageData, ...)!force-unwraps and traps on any image the re-encode can't handle.1.0+ completion even when the change block staged zero resources or PhotoKit returned an error. PhotoKit reports an emptyperformChangesas success, so a failed save is indistinguishable from a real one.…/<random>.mp4temp path, discarding the source's real extension (e.g..mov).This is still present on
master(ffd82647); the recent engine refactor didn't touch this logic.Changes
.mp4.!force-unwrap with aguard let.Public signature is unchanged; all call sites are unaffected.
Proof
The full app build is Bazel/device-only, so I verified the control-flow fix with a standalone Swift harness that transcribes the OLD and NEW authorized-closure flow over a real
FileManagerwith PhotoKit/export results injected:i.e. the old flow either hangs, crashes, or reports success while saving nothing; the new flow always completes and the media lands.
🤖 Generated with Claude Code