Question

Cocoa's WebView can display .webarchive files. The ones I try to display come from the pasteboard, e.g. when copying parts of a web page in Safari or Mail.app.

The issue I am having is that webarchives from Mail and Notes won't display in a WebView, while webarchives from Safari do.

I looked inside the data of those archives (BBEdit can decypher their binary plist format and show it as XML nicely) and found that the issue is caused by the unusual URL references Mail (and Notes) puts in there:

<key>WebResourceURL</key>
<string>x-msg://4/</string>

If I remove that entry or change it to something using http://, WebView suddenly can display such archives.

Now, how do I solve this in general in my code?

I don't want to have to decode the webarchive, find the WebResourceURL entry and remove it before passing the archive to the WebFrame for loading.

I wonder if there's something else I have to set up with either the WebView or its main frame to make this work.

I noticed that Xcode can show these webarchives just fine, suggesting that Xcode uses WebKit in a more "proper" way that solves the issue. But then, maybe that's just because it has NSWebFrame load the archive from disk, while my code loads it from a CFData object - when loading from a file, WebKit may be using that file URL as the base URL, while it only chokes on it when it doesn't get a usable URL at all.


I have created a little demo project for Xcode here: http://files.tempel.org/Various/Mail-WebArchive-Display-Issue.zip

It includes both an original archive from Mail ("mail-bad.webarchive") and a fixed one ("mail-good.webarchive"), both of which are displayed in two webViews in the demo app.


I had also opened a Tech Support Indident (TSI) with Apple DTS, and the responded that I should file a bug. The bug report can be seen here: http://openradar.appspot.com/radar?id=2843403

Was it helpful?

Solution

After brooding over what Xcode might be doing I found a solution:

This does not work:

WebArchive *archive = [[WebArchive alloc] initWithData:webData];
[[webView mainFrame] loadArchive:archive];

But this does:

[[webView mainFrame] loadData:webData MIMEType:@"application/x-webarchive" textEncodingName:@"" baseURL:NULL];

So, the explicit function to load the archive is faulty while the one that wants an explicit URL, even though I give it none, works.

Go figure.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top