URL Schemes and Fallback - Pixate/pixate-freestyle-ios GitHub Wiki
This article discusses custom schemes added by the Pixate Engine that can be used in your styling URLs. These schemes allow you to specify files independently of where you run your app: on the Simulator or on device. Additionally, URLs without a scheme activate a fallback mechanism that can be useful for changing content in an application, even after it has been deployed.
The file scheme allows you to access files on your device or on your desktop's file system when running in the Simulator. Of all of the supported schemes, the file scheme is the most basic. Think of the other schemes as convenience forms of this scheme.
Due to path differences when you run on the Simulator versus when you run on device, you're unlikely to use this scheme directly. However, it can come in handy when you want to save or to access files on your desktop from the Simulator. For example, the following URL could be used to reference an image in your machine's Desktop folder. This would allow you to make changes to the image and then to display the new version in your app while it is running, something that is very useful during the design phase of your app.
file:///Users/myname/Desktop/sample-image.png
Paths change depending on how you run your app. To obivate these differences, the Pixate Engine introduces new schemes to access known folders in all run conditions.
iOS provides access to a 'Documents' folder in your running app. Since the OS provides this location for us, we can safely calculate a path relative to that spot. Thats where the documents:// scheme comes in. For example, the following URL references a file in the app's Documents folder:
documents://sample-image.png
When you add resources to your app, these are included in the app's default bundle. The bundle:// scheme is used to access these files.
bundle://sample-image.png
You may have noticed that many of the Pixate Engine samples use URLs without a scheme. These types of URLs give the Pixate Engine some freedom as to where it looks for files. Specifically, the Engine first looks in the Documents folder. If it doesn't find the file there, then it looks in the default bundle. For example, if we use the following URL:
url('sample-image.png')
The engine will first look in the Documents folder as if we had used the documents scheme.
url('documents://sample-image.png')
If the image isn't found there, then it looks in the application bundle as if we had used the bundle scheme.
url('bundle://sample-image.png')
Why do we do this? Well, it turns out that your app cannot alter the contents of the default bundle while it is running; however, it can alter the content of the Documents folder. This opens up some interesting possibilities. For example, let's say your application provides a default image that you wish to change after the first run. Your app can download a new image, save it in the Documents folder using the same name. As long as you reference the image with an implicit URL, the next time a style uses that URL, the downloaded image in the Documents folder will be used in place of the one in the default bundle. You have changed resources used for styling without having to alter your app nor its CSS.
Lets walk through the setup of a sample application to demonstrate these schemes in action.
For this example, use a Single View Application. A couple of SVG files are added to the project as seen below in the image of the default bundle folder on the simulator.
Next, add some more SVG files to the Documents directory of the app. One file has the same name, circle.svg, as a file in the bundle and another file does not match any files in the bundle.
In Interface Builder, add 9 views to your app's view. Using User-Defined Runtime Attributes, set their styleIds to view1 through view9. Now, create a default.css and paste the following code into that file.
#view1 {
background-image: url('circle.svg');
}
#view2 {
background-image: url('documents://circle.svg');
}
#view3 {
background-image: url('bundle://circle.svg');
}
#view4 {
background-image: url('circle2.svg');
}
#view5 {
background-image: url('documents://circle2.svg');
}
#view6 {
background-image: url('bundle://circle2.svg');
}
#view7 {
background-image: url('circle3.svg');
}
#view8 {
background-image: url('documents://circle3.svg');
}
#view9 {
background-image: url('bundle://circle3.svg');
}
We're all set. When we run the app, we get something like the following:
There are a few things to note about the images that are loaded in the above example.
- url('circle.svg') - This loads the image from the Documents folder, preventing the loading of the version in the app bundle
- url('documents://circle.svg') - This confirms that the implicit URL is loading from the Documents folder
- url('bundle://circle.svg') - Even though the implicit URL didn't load the app bundle image, we can still get to it
The other examples follow similarly. However, you may want to note that documents://circle2.svg and bundle://circle3.svg are white because no images exist at those URLs.
In this tutorial, you have learned about the following types of schemes:
- file://
- documents://
- bundle://
- implicit scheme
These give you a high degree of control when referencing resources, in a manner that's independent of the Simulator and a device. Perhaps the biggest gain is the use of the implicit scheme which allows you to dynamically change your styling content on-the-fly, even after your app has been deployed.
Enjoy!
[Published: 2013-04-12]