Display WebArchive from Mail.app and Notes.app - cocoa

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

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.

Related

Injected Javascript from Safari App Extension stops working once I make any modification

I'm trying to develop my first Safari App Extension and I followed Apple's document on building a safari app extension and my Xcode version is 11.5. It appears that the extension worked, as I can see the extension button loaded on Safari navigation bar, and I can get the "Hello World!" from the injected script.js in SFSafariExtensionHandler subclass's messageReceived method when a page is loaded in Safari. So far so good with all with the code auto generated by Xcode when the Safari Extension was added. However, any modification of the script.js, like adding a new empty line, or just repeating the same dispatchMessage call, would render the extension unable to run , like the code below:
document.addEventListener("DOMContentLoaded", function(event) {
safari.extension.dispatchMessage("Hello World!");
safari.extension.dispatchMessage("Hello World!");
});
This is very frustrating, particularly considering the auto generated extension code already generates a ton of warning and error messages even when it appeared to be working. But I do see there are many Safari Extension products in App Store, so could anybody point me in the right direction?
Figured this out: we have to clean the build every time the script is modified. Then the extension debug run works again. Cleaning also works if we modified the info.plist and get code signing errors in debug runs.

how app extension can access the containing app images/assets/resource data

I implemented the document provider app extension feature with my own
ios app. The problem is the app extension was not able to access the
containing app images/assets or the containing apps resource data.
Does any one knows how to achieve it?.
The extension has its own target in your Xcode project. In order to access resources in the extension you also need to add them to that target (in the File Inspector also check your extension target in the Target Membership section). Just be aware that those resources also get copied into the extension bundle, which increases your overall app size.
Sidenote: In my extension I didn't add my default image asset catalogue (Images.xcassets) to the extension, but was still able to access the containing images. Maybe that's an exception.
UPDATE
If you are supporting iOS 8 and up, you can create a framework to share among your app and it's extensions, and embed resources, strings, etc. inside of it. Make sure to use the [UIImage imageNamed:inBundle:compatibleWithTraitCollection:] and NSLocalizedStringFromTableInBundle methods, passing in the bundle that is your framework.
PREVIOUS ANSWER
Given that extensions are (and hopefully always will be) in a sub-folder of the main app at /Plugins/PluginName and have permissions to access files just like the main app, you can do the following (and I do in some of my apps on the store):
// image
UIImage* image = [UIImage imageNamed:#"../../image_name.png"]
// data
NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:#"../../file.json"];
NSData* data = [NSData dataWithContentsOfFile:path];
This will save you a lot of space, especially if your extension uses a lot of images.

Reading multiple PDF files in Preview app Mac OS X Maverick

I need to work on multiple PDF files and because of annotating those files, I prefer to use Preview built-in app for Mac OSX.
If I am in the middle of one PDF file say on Page 5, and I transit to some other PDF file and come back to the previous file, then I always get the first page of that PDF.
Is there any setting which I can use so that I always get the page from where I left?
Not sure what the problem is, mine works as you seem to want it to. Maybe your Preferences are set differently. Here are mine.

Cocoa WebView (MacApp) - how to use custom fonts?

I have a WebView in a Cocoa application (macgap).
(NOTE I'm not talking about a UIWebView in an iOS app)
In my CSS file, there are some custom font declarations:
#font-face{
font-family:'Quivira';
src:url("./Quivira.ttf") format("truetype");
font-weight:normal;
font-style:normal;
}
I can't get these to load however - some sort of security issue I believe.
Sometimes, I can see there is an error in the console "Not allowed to load local resource: Quivira.ttf" (it doesn't always show this though)
What could be causing this? The index.html file is loaded via the file:/// protocol so there shouldn't be a security issue, as it is already local and should therefor be able to load local resources.
I'm thinking it could be a bug in webkit.
Is anyone able to load custom fonts in a Cocoa WebView?
I have tried two approaches to load webpages with custom fonts.
From the app bundle (using NSBundle)
From a local path specified by the user (using absolute path)
In both cases I am successfully able to display Custom Fonts. There is a HTML file and beside it, a .ttf font file. In the HTML file I have defined #font-face in inline CSS.
In the second case you can give any full path from local filesystem and the webview will load from that (like /Users/johndoe/Desktop/maiwebsite/index.html).
Code is on Github.
And from another answer on SO:
Instead of getting the resource path and stapling a subpath onto it yourself, ask the bundle to give you the correct path.
Instead of handling a path at all, ask the bundle to give you the correct URL. (Requires Mac OS X 10.6 or later.)
If this doesn't help then could you put up your code somewhere so we can try to debug it?
For WKWebView (WebView now deprecated), load custom fonts from the MacApp bundle like so:
[_webView loadHTMLString:htmlContent baseURL:[[NSBundle mainBundle] resourceURL]];
Unlike iOS where all one needs to supply for bundle resources is: [[NSBundle mainBundle] bundlePath] (iOS Bundle is flatter), for MacApps the path to resources is more complex and bundlePath alone will NOT work. The above approach DOES work.
In your CSS simply use #font-face like so and any fonts in the location specified by resourceURL will be found.
#font-face {font-family:'myfont';src:url('myfont.ttf');}

Browser add-on to find a download's origin

Back in the earlier days of the internet I remember that in certain browsers, every time you downloaded an image or a file, the URL of where that file was downloaded from would be written into that file's properties (I guess the summary tab?). I think Netscape v2 did this if I remember correctly.
I really miss that kind of functionality as every once in a while I'll run into a neat little program stored somewhere in the depths of my hard drive and wonder where I got it from originally.
I googled around but I'm not quite sure what terms to use to describe what I'm looking for. So I'm wondering if anyone knows of a Firefox plug-in or something similar that would do this?
If you use the DownThemAll! extension for Firefox, you can tell it to prepend the URL of the site to the downloaded file name...
thus you end up with files like:
download.com_utils_compression_ABCD32.exe
It also works really well when you want to download/queue a bunch of files.
You download http://example.com/foo to ~/Desktop/foo, and you want to see the originating URL in the properties of the local file foo?
Back when I used OS X, I remember Safari used to record the original URL in the resource fork of the downloaded file. Can't remember what the named fork is, well, named, but it'll show up in the properties panel from Finder. Since it's there, Spotlight will probably index it, too, but I haven't used OS X since 10.3.
If you use Opera, and haven't cleared the file out from your download manager, select the download and it'll show the original URL that the file is from in the properties pane.
Is this what you want? If so... well, I don't know of a similar Firefox extension, but it'll clarify the question.
For the IE Browser I use the hell out of Fidler to look at all traffic going across the wire.
For FireFox, you can use the FireBug plugin. There is a "Net" tab that will show you request information that is going across the wire.
Most of the time you can use one of these tools to see what URL was requested in order to start a download. You can also view all the get and post information that might need to be sent in order to have your request succeed.
Fidler is here: http://www.fiddlertool.com/fiddler/
FireBug is here: https://addons.mozilla.org/en-US/firefox/addon/1843
Best of Luck!

Resources