After the OS X Lion upgrade I couldn’t get my Time Machine to work with my Ubuntu based Nas. It turns out Apple bumped the required AFP commands to make it work with TimeMachine. You need AFP 2.2 under Ubuntu to make it work. As I was to lazy to compile it myself I found a easier solution.

sudo add-apt-repository ppa:stefanor/ppa
sudo apt-get update
sudo apt-get install netatalk

Afterwards your TimeMachine should work again.

If you can’t see your TimeMachine Share in the Disk Selection of TimeMachine make sure you executed the following command:

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
Bonus:

If you want to limit the size Time Machine will use just appendĀ volsizelimit:500000 to your Time Machine share inĀ /etc/netatalk/AppleVolumes.default

500000 is 500 GB

Example of my /etc/netatalk/AppleVolumes.default:

/media/nas/TimeMachine/ TimeMachine options:tm,usedots,upriv,volsizelimit:500000

As you probably know we’re at liip are doing the HTML5 based Webapps. Now our customer wishes to have his iPhone / iPad HTML5 to be accessible offline.

As I found this topic super interesting I started writing a proposal how in my opinion this goal could be achieved best. As our content is highly dynamic (news articles) the normal html5 cache manifest just won’t cut it.

Off course we will store css, js and static images in the cache manifest. But from what I read it is just not the right place for highly dynamic content.

Now let’s cut to the cheese and come to my plan:

Caching the Page

Responses from the backend will be stored by their url in the local storage. Example:

key => /2011/09/05/schweiz
value => <html><body>foo bar page content</body></html>

We wrap the YUI IO Object and upon each request we check if the requested URL is not already stored in our local storage. If so we will call the callback function directly and feed it the response from the local storage. That way the user will have a super fast experience if the response is already in the cache.

Caching the Images

Caching the images is another problem as the browser gets their content on his own. They also get stored by their path in the local storage. Example:

key => /image/large_cropped/article/2011/09/05/N_IVTZU/image/IWIGD-ein-davoser-als-ehrenbuerger-des-suedsudans

The value in this case needs to be base64 encoded value of the binary stream. The backend image API will offer the option to request the image base64 encoded rather than just returning the normal image.

The pictures nodes that are not fed by the cache manifest won’t have a src tag anymore on the iPad / iPhone view. Their url is stored in some other attribute. In this example I’ll use base64Src=”" as the attribute. This will prevent the browser from loading the pictures whenever it’s actually online. That way we prevent the browser from fetching content we already have.

Once a request is loaded / delivered from the cache, we will loop through all the tags and populate the images. To do that we can simple read the base64Src attribute. If they’re not yet cached we will request them through XHR. Afterwards we can fill the images with a little javascript trick:

document.getElementById("hero-graphic").src='data:image/jpeg;base64,' +
localStorage.getItem('/image/large_cropped/article/2011/09/05/N_IVTZU/image/IWIGD-ein-davoser-als-ehrenbuerger-des-suedsudans')

Prefetching

All this fancy caching won’t give much benefit if we don’t build a prefetching mechanism. Once the page is fully loaded and in a somewhat “idle” state we will start prefetching content.

To know what should be prefetched, we will request a list from the backend which contains the urls of all pages that need to be prefetched as well as all the necessary images. Doing it like that gives a few very nice possibilities:

  • The backend is in control which pages are stored localy, so it can easily change every day.
  • We fetch content sequentially, this means in case of interruption the user doesn’t lose all of his download, just the data from the currently active request.
  • As we already know how many articles and images we have to fetch we can calculate a quite accurate progress bar
  • We have the possibility to pause the downloads at any time. The user would only lose the current request.

This whole approach would give us a solid prefetching without having to touch much of existing code. We can also implement nice UI features like the ability to see the download status as well as making it configurable how much content should be stored.

The only problem I see currently is that we don’t have a way to tell if the iPhone / iPad is online or offline. We could try to detect that based on the IP the request has in the backend or in the time it takes to prefetch the first article. Sadly there’s no isWifi boolean exposed to javascript as far as i know.

What do you think about it? Any comments, corrections or better approaches are appreciated.

I develop quite a lot javascript these days and a perfect tool to ensure code quality is JSLint. Back then I had it integrated into TextMate, the same can be done to Sublime Text 2 through it’s build Environments. I’m going to show you how to do it: 1. Create a new Build Environment in [...]

I used to have an iPhone and what I really liked was the ability to control iTunes through the Apple Remote app. Now there’s an App for that on Android. It’s called TunesRemote+. The Process is the same as it was with the iPhone: 1. Install the App 2. Pair your device with your iTunes [...]

I tried Ubuntu 10.10 now for 14 days and I think I need a break and will return to Mac OS X. Trying to find out what I really want and really like. The main reason is that I currently have to learn so much new stuff in the office and are pretty busy with [...]

Just a short list that Displays the Software alternatives I chose when I switched to Ubuntu from OS X Music: iTunes => Banshee Twitter: Tweetie => Gwibber IRC: Linkinus => XChat-GNOME Office: MS Office 2011 for Mac => Office 2007 (Wine) * Photo Library: Aperture => Shotwell Photo Manager Picture manipulation: Photoshop CS5 => Photoshop [...]