Adds the 'rsrc:///' URL scheme to an OS X or iOS app's URL loading system, allowing direct access to bundle resource files.
GGLResourceScheme is a dead simple NSURLProtocol subclass that adds the rsrc:///
URL scheme to the URL loading mechanism of an OS X or iOS app. It’s not exactly rocket science, but enough people expressed amazement that this could be done that I thought I’d throw up a simple, useful example library.
During your app’s initialization, call [GGLResourceScheme registerResourceURLScheme]
.
Then, from almost anywhere within cocoa or cocoa touch that you can use a URL, you may use an rsrc:///BundleResourceName.ext
URL (where BundleResourceName.ext
is the name of a file within your app’s bundle resources) to gain direct access to your app’s resource files.
For example, if you use a WebView for internal UI rendering, and you want to link to CSS or JavaScript files stored in your app’s resources, or you want easy access to your app’s images, you might load HTML that looked like this:
<html>
<head>
<script language="javascript" src="rsrc:///common.js"></script>
<link rel="stylesheet" type="text/css" href="rsrc:///common.css">
</head>
<body>
<img src="rsrc:///logo.png">
</body>
</html>
(Where common.js
, common.css
, and logo.png
are all files you’ve included in your app’s bundle resources via Xcode.)
The easiest way to add GGLResourceScheme to you project is to simply download the GGLResourceScheme.h
and GGLResourceScheme.m
files from the repo, and import them into your project.
The GGLResourceScheme project itself is an Xcode project with targets to build static libraries for either OS X or iOS. An advanced user could add GGLResourceScheme to their project as a git submodule, and then build and link the library as a dependency, however, this is probably overkill and instructions to do so are beyond the scope of this readme.
An rsrc
can be thought of as equivalent to a file
URL that points at your bundle’s resource path instead of at the root of your drive. As with a file URL, there is no domain, only a path, (or more correctly, the domain is localhost
) and therefor the correct format is 3 slashes after the colon. (i.e. rsrc:///FileName.ext
) (See This Superuser Question for more info on why.)
Under the hood, GGLResourceScheme uses the [[NSBundle mainBundle] URLForResource:withExtension:]
method to find your bundle’s resources. It should be able to find any resource that could be found by that method.
An rsrc:///
URL simply finds the URL for the resource, and the forwards the URL loading system to the appropriate file:///
URL. This has a few security implications. Many URL clients, including WebKit, treat file:///
URLs as special and privileged:
In a WebView
or UIWebView
, a page loaded via an http://
URL generally cannot load a local file:///
URL. This is a desirable security feature, and the main reason rsrc:///
URLs are designed to forward to file:///
URls.
However, because of this security feature, in some cases URL clients will refuse to follow a redirect from a non-privileged URL to a privileged URL. In these cases, rsrc
URLs provided by GGLResourceScheme won’t work, and may fail silently. On iOS only, a UIWebView will not allow an rsrc:///
URL to be loaded into it’s main frame. It will still allow images, javascript, and CSS to be loaded via rsrc
URLs, however. (This is not an issue on OS X thanks to the [WebView registerURLSchemeAsLocal:] method, which allows GGLResourceScheme to mark rsrc
URLs themselves as privileged. Alas, no equivalent appears to exist on iOS.)
GGLResourceScheme is available under a Simplified BSD License. Please see the License.txt file.
I am @peteburtis on app.net.