DEV Community

王磊
王磊

Posted on

Why My iPhone File Picker Greyed Out Every PST File I Asked For

WebKit maps accept extensions to MIME types, drops the ones it doesn't know, and then limits the Files app to whatever is left. For a mail archive tool, that is almost everything that matters.


I run a browser tool that opens Outlook .pst and .ost files without Outlook. For months the homepage said it worked on a Mac, a PC, a Chromebook, or an Android phone. Google was suggesting "open pst file on ipad" next to "on android" and "on chromebook". Bing showed tablet-flavoured queries. The site said nothing about an iPad or an iPhone.

That gap was not just marketing. On iOS the file picker itself can quietly refuse the files the page is built for. Here is what I measured, why the picker behaves that way, and what the page now does about it.

First, does the engine even open a PST?

Before writing any "works on iPad" claim, I ran the live site in Playwright's WebKit 26.6 with the iPad Pro 11 and iPhone 15 profiles. That is Apple's engine in an emulated viewport, not a physical iPad's memory or its Files UI, so the claim has to stay within what that run shows.

Results with the public Enron test PST (14 MB, read whole) and a 108 MB copy (read in pages):

  • 11 folders and 71 messages opened in about 0.8 seconds
  • search returned hits
  • tapping a message opened it
  • no page errors, no sideways scroll

So the readers work in WebKit. PST, OST and MBOX are read in pages rather than held whole in memory, which is the same path Android and desktop use for large files. That is the engine half of the story. The picker is the other half.

What <input accept=".pst,.ost,…"> does on iOS

On iPhone and iPad every browser is WebKit. When a page sets the file input's accept attribute to a list of extensions, WebKit does not pass those extensions through to the Files app as filenames. It looks each one up in the system's extension-to-MIME table and drops any extension that has no entry.

Of the archive types this tool accepts:

Extension iOS has a MIME mapping?
.eml yes (message/rfc822)
.zip yes (application/zip)
.pst, .ost, .olm, .mbox, .msg no

If anything survives that lookup, the Files picker opens limited to the survivors. A homepage that listed .pst,.ost,.eml,.mbox,… therefore opened a picker in which every archive type but .eml and .zip was greyed out — including the .pst the visitor came to open.

If nothing survives, the picker allows every file. So the failure mode is not "no accept breaks iOS". It is "a mixed list that includes one known type silently filters out every unknown type".

(The WebKit side of this lives in WKFileUploadPanel and the Cocoa MIME registry: extensions go through UTI / MIME lookup before the menu is shown. I am not claiming a new WebKit bug; I am describing the behaviour a page has to work around.)

This matched older analytics too: across ninety days there had been iOS visitors and zero successful opens. The engine was fine. The picker was the wall.

The rule the page uses now

The accept string is built by a small helper. On an Apple touch device it is kept only when every listed extension is one iOS can type. Otherwise it is left off, and the content check that already runs after a pick tells a wrong file apart.

export const IOS_TYPED_EXTENSIONS: ReadonlySet<string> = new Set([
  "eml",
  "zip",
]);

export function fileInputAccept(
  formats: readonly string[],
  appleTouch: boolean,
): string | undefined {
  if (formats.length === 0) return undefined;
  if (appleTouch && !formats.every((f) => IOS_TYPED_EXTENSIONS.has(f))) {
    return undefined;
  }
  return formats.map((f) => `.${f}`).join(",");
}
Enter fullscreen mode Exit fullscreen mode

Detecting "Apple touch" needs one extra check: modern iPadOS often sends a Macintosh user agent, and gives itself away by having a touch screen (maxTouchPoints > 1). Matching only /iPhone|iPad|iPod/ misses those iPads.

A page that accepts only .eml and .zip still gets an accept attribute. A page that mixes in .pst or .mbox does not. Tests pin both the helper and the homepage copy to that set, so a future format list cannot drift from the FAQ.

What the homepage now says

The hero line names an iPad next to the platforms that were already there. A new FAQ answers "Can I open a PST file on an iPad or iPhone?" with the practical path:

  • Yes, in Safari.
  • Tap the drop area and choose the file in the Files app.
  • The picker lists every file, because naming archive types by extension would grey most of them out.
  • Whatever you choose is checked by its contents once picked.
  • Large PST / OST / MBOX files are still read in pages.

The same platform line went into llms.txt, so answer engines that quote the site don't keep saying "Mac, PC, Chromebook, Android" and stop there.

Limits I am not papering over

  • The WebKit run is an engine-and-layout check. It is not a measurement of a specific iPad's free RAM, nor of every Files location (iCloud Drive, On My iPhone, shared folders).
  • Leaving accept off means the picker shows photos, PDFs and everything else. That is deliberate. The content sniffer rejects non-archives after the pick; the cost is one extra tap for someone who picks the wrong file.
  • OLM, ZIP and MSG are still read whole into the tab. A phone runs out of memory for those sooner than a laptop. The iPad answer sticks to PST / OST / MBOX for the paging claim, which is what the code actually pages.

Takeaways

  • On iOS, accept is a MIME filter in disguise. Unknown extensions vanish; known ones become the only things you can tap.
  • A mixed list is worse than no list, if your product's main format is in the unknown set.
  • Omit accept when you cannot name a typeable set, and validate by content after the pick.
  • Detect iPadOS by touch points, not by the word "iPad" in the user agent alone.
  • Don't claim a platform in the hero until the picker path on that platform has been walked.

If you need to open a PST on a tablet without Outlook, the homepage walkthrough is on Mailward. Disclosure: I built it. The file stays on the device; Safari opens it locally.

Top comments (0)