Skip to content

feat(ios): support the fileName option for tmpfile captures (#552) - #760

Open
officialasishkumar wants to merge 1 commit into
gre:masterfrom
officialasishkumar:feat/ios-file-name
Open

officialasishkumar wants to merge 1 commit into
gre:masterfrom
officialasishkumar:feat/ios-file-name

Conversation

@officialasishkumar

Copy link
Copy Markdown

Closes #552

What: iOS now reads the fileName capture option. When result is "tmpfile", the file is written to tmp/ReactNative/<fileName><UUID>.<ext> instead of always tmp/ReactNative/<UUID>.<ext>. Without fileName, nothing changes.

Why: fileName was Android only, so on iOS the name a share target shows (WhatsApp, Mail, etc.) could not be controlled. I gave it the same meaning as on Android, where it is the prefix passed to File.createTempFile (as #740 noted), instead of the exact-name approach from the patch in the issue:

  • the unique suffix means two captures with the same fileName never overwrite each other, and releaseCapture on one cannot delete the other;
  • the file stays a direct child of tmp/ReactNative, the only directory releaseCapture deletes from, so releasing these captures still works;
  • the path still comes from RCTTempFilePath, so its first-use cleanup of tmp/ReactNative keeps working the same way.

Like Android, a fileName shorter than 3 characters rejects the capture. A fileName containing / or a NUL byte is rejected too (fileName must be at least 3 characters long and must not contain '/'), so it cannot point outside the directory.

How: The path logic is a private class method, +[RNViewShot tempFilePathWithExtension:fileName:error:], which the tmpfile branch calls instead of RCTTempFilePath. The XCTest target can call it without an RCTBridge, in the same way RNViewShotReleaseCaptureTests calls releaseCapture:. The README and the CaptureOptions JSDoc now describe fileName for both platforms.

Tests: New cases in RNViewShotEncodingTests.mm:

  • without fileName, the result is still a bare <UUID>.png in the RCTTempFilePath directory;
  • with fileName, the name starts with the prefix, ends with the extension, stays in that same directory, differs between two calls, and can be written;
  • "", "ab", "../escape", "dir/name" and a name containing NUL are rejected with an error.

Verified:

  • npm run format:check, npm run lint:ci, npm run type-check and npm test (104 tests) pass.
  • I didn't run the XCTest target locally. I compiled the new method on its own with clang (with RCTTempFilePath/RCTErrorWithMessage stubbed to match React Native) and ran the same checks the XCTests make; they all passed. The ios CI job runs the real XCTest target.

`fileName` was documented as Android only: iOS ignored it and always
wrote `tmp/ReactNative/<UUID>.<ext>`, so apps sharing a capture (e.g.
through react-native-share) could not control the name the receiving
app shows.

iOS now gives `fileName` the same meaning as on Android, where it is
the prefix passed to File.createTempFile: the file is
`tmp/ReactNative/<fileName><UUID>.<ext>`. Keeping the unique suffix
means two captures with the same fileName never overwrite each other,
and every capture stays a direct child of tmp/ReactNative, the only
directory releaseCapture deletes from. Like Android, a fileName
shorter than 3 characters rejects the capture; a fileName containing
'/' or a NUL byte is rejected too, so it cannot leave that directory.

The path logic lives in a private class method so the XCTest target
can cover it without an RCTBridge: default name unchanged, prefix and
uniqueness with a fileName, and rejection of invalid names. README and
the CaptureOptions JSDoc now describe the option for both platforms.
Copilot AI balanced review requested due to automatic review settings November 2, 2026 18:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the iOS filename-prefix support change.

No open issues 🎉

What changed in this PR

Adds iOS support for the fileName capture option, addressing #552 with Android-compatible prefix semantics while preserving unique temporary filenames and existing cleanup behavior.

Changes:

  • Adds an iOS temporary-path helper that validates prefixes and retains the unique suffix generated by RCTTempFilePath.
  • Adds XCTest coverage for default filenames, unique prefixed filenames, writable paths, and invalid input.
  • Documents fileName support and prefix behavior for both Android and iOS.
File Description
src/​index.tsx Updates CaptureOptions.fileName documentation for both platforms.
README.md Describes filename prefixes, uniqueness, and validation constraints.
ios/​RNViewShot.mm Implements validated filename prefixes for temporary captures.
example/​ios/​ViewShotExampleTests/​RNViewShotEncodingTests.mm Tests default, prefixed, and invalid temporary filenames.

Review effort: Balanced

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.

[Feature] Add support fileName propertie on iOS for captureRef method

2 participants