Summary
On iOS Safari (and WKWebView-based browsers), when a web page uses <input type="file" accept="image/*" capture="environment"> (or capture="user"), the user can only ever hold one captured photo at a time. Each time the file picker is opened and the user takes a new photo using the camera, the newly captured image completely replaces the previously captured image in the input's files FileList. There is no way to accumulate multiple camera-captured photos across successive picker sessions.
Steps to Reproduce
- Set up a web page with an
<input type="file" accept="image/*" multiple>element (with or without thecaptureattribute). - Open the page in iOS Safari on an iPhone.
- Tap the file input — choose Take Photo from the action sheet.
- Capture a photo and tap Use Photo.
- Verify
input.files.length === 1(first photo is captured). - Tap the same file input again — choose Take Photo again.
- Capture a second photo and tap Use Photo.
- Check
input.files.length.
Expected Result
input.files.length should be 2 (or more), containing both the first and second captured photos. The browser should accumulate photos across picker sessions when the multiple attribute is present.
Actual Result
input.files.length is 1 — only the most recently captured photo is present. The previously captured photo is completely gone. Every new camera capture wipes out all prior selections.
Root Cause Analysis
- On iOS, each invocation of the system file picker (whether using the camera or photo library) creates a brand-new
FileListand assigns it to the input element, discarding any previously selected files. - The
FileListinterface is read-only per the HTML spec — web developers cannot programmatically appendFileobjects to it. - The
DataTransferAPI workaround (constructing a newFileListviaDataTransfer.items.add()) does not work on iOS Safari — theDataTransferconstructor is not supported for programmatic file list manipulation in file inputs on iOS WebKit. - This is specific to iOS. On macOS Safari and all desktop browsers, users can select multiple files in a single picker session, avoiding this issue.
Impact
This makes it impossible to build a web-based multi-photo capture workflow on iOS using standard HTML APIs. Common real-world use cases that are broken:
- Uploading multiple photos of a document one page at a time
- Capturing multiple product photos for a listing
- Progressive photo capture in inspection or form-filling apps
- Any PWA or web app requiring sequential camera captures
Users must select all photos in a single picker session. If they tap "Cancel" or close the picker, all prior captures are permanently lost.
Request
Please fix WebKit on iOS so that when <input type="file" multiple> is used, re-opening the file picker either:
- Accumulates newly selected/captured files into the existing
FileList, or - Presents the system picker with previously selected files pre-checked (similar to how macOS handles re-opening file dialogs), or
- Exposes a web API (e.g., via the File System Access API's
showOpenFilePicker()with multi-select) that developers can use to manage a cumulative file collection on iOS.
Environment
- Devices: iPhone 13, 14, 15 Pro (physical devices)
- iOS versions: iOS 16.x, 17.x, 18.x — all affected
- Browser: Safari (Mobile)
- Also reproduced in: Chrome for iOS, Firefox for iOS (both use WKWebView)
- Not reproducible on: macOS Safari, Chrome desktop, Firefox desktop
A Feedback Assistant report has been filed. Happy to provide a minimal HTML repro page on request.
Thank you for the well-structured report — accurate technical analysis, clear repro steps, and complete environment notes make this kind of question much easier to engage with.
Your diagnosis is correct in every detail. I built a small WKWebView test app, bundled minimal HTML pages mirroring your setup, and confirmed both the symptom you describe and a JavaScript-level workaround on:
- iPhone 17 Pro Max simulator running iOS 26.4.1
- iPad Pro 13-inch (M4) running iPadOS 26.4.2, with both the Photo Library path and camera capture path
In every test, input.files.length resets to 1 (or to whatever the most recent picker session selected) — exactly the behavior you observed. So the picker-replaces-FileList behavior persists into the current iOS/iPadOS 26.4 line, beyond the iOS 16–18 range you tested.
A workaround that doesn't require WebKit changes
You don't actually need input.files itself to accumulate. You just need to keep references to the File objects. The picker session wipes input.files, but File objects you've kept in a JavaScript array of your own remain valid:
const accumulated = [];
const input = document.getElementById('picker');
input.addEventListener('change', () => {
for (const f of input.files) {
accumulated.push(f);
}
// input.files gets wiped on next picker; accumulated stays.
});
// Later, when you submit:
function submit() {
const fd = new FormData();
accumulated.forEach((f, i) => fd.append('photos[]', f, f.name));
fetch('/upload', { method: 'POST', body: fd });
}
In my test app, accumulated.length grew correctly with each successive picker session (both photo library and camera), and a FormData built from the accumulated array contained every captured File. So your DataTransfer constructor analysis stands — that path doesn't work — but you don't need it. The File references are stable across picker sessions. Only input.files changes between sessions.
What the workaround doesn't solve
The UX is still N taps for N photos — each camera capture is its own picker session, and your customer has to tap the input, take a photo, tap "Use Photo", and return to your page once per image. The accumulator pattern only addresses the data-side issue (keeping the captures), not the interaction overhead. If the UX of repeated tapping is what's most painful for your customers, that's where your enhancement request to WebKit comes in.
On your enhancement request
The three options you outlined — accumulate on picker reopen, present the picker with previously selected files pre-checked, or expose an additional file-system API — are all reasonable framings. The Feedback Assistant is the right channel.
Please file an enhancement request using the Feedback Assistant so that your request can be seen by the appropriate decision makers. If you file the request, please post the Feedback number here so we can make sure it gets routed to the right team.
Please note that filing an enhancement request does not guarantee Apple will add any requested functionality to Apple products in the future. However, with that said, filing an enhancement request is a good way to get your ideas in front of the folks who make decisions about that sort of thing.
If you're not familiar with how to file enhancement requests, take a look at Bug Reporting: How and Why?.
You mentioned you'd already filed a Feedback Report — if you have the FB number handy, post it here so I can track it.