Over-the-air Ad-Hoc Distribution on Speed

I recently read another blog post about OTA (Over the Air) distribution of Ad-Hoc builds of iPhone applications and thought I’d share my own thoughts on this.

I’m doing a lot of client work and try to maintain very short feedback cycles. Sometimes this means that I may send out multiple Ad-Hoc builds for one application a week to get constant feedback from my clients. My “traditional” approach was to build the Ad-Hoc build, put it in an email and send it to the client. The client then had to sync his device with iTunes to get the latest build. As many of you know, this becomes frustrating very quickly.

Not so long ago Apple enabled OTA distribution of Ad-Hoc builds, which means you can export the Ad-Hoc build from Xcode, put it on a webserver and have the client install it over the air right from Safari. (For a detailed instruction on how to do this, check out this article by John Muchow who has written a great detailed instruction on how to do this). So because it seemed so much easier for my clients I did that for a while and basically had a list with all the URLs to enter which i could just use by copy/pasting them into Xcode while saving the .ipa file.

But if you do this manually a couple of times, you notice that it is really annoying and time consuming. Something that needs to be automated. So that’s what I did. I built a small application for exactly that purpose and it’s called IPA Publisher. If you want to check it out, visit the Mac App Store and get it for just $4.99.Note: Unfortunately, IPA Publisher is still in review so you won’t find on the App Store yet. But since I have a short talk at NSConference 2011 about it, I wanted to publish this post anyway so people could come back to it. If you want to know how it works, keep on reading:

The basic idea

The basic idea behind IPA Publisher is to relieve you of the tasks of entering the location information over and over again. You enter details about one (or more) locations where you publish Ad-Hoc builds once (e.g. a public Dropbox folder, your webserver, …), and then every distribution of a new build comes down to:

  • Build and Archive an Ad-Hoc build
  • Save the .ipa file (no Distribute for Enterprise and entering all the location details, but instead just choosing Save to Disk)
  • Hand the .ipa to IPA Publisher
  • Choose the location where you want to publish it
  • Have all the necessary files generated (.plist, website and provisioning profile).
Instead of talking a lot about it, let me demonstrate this with a simple example by using the Dropbox Public Folder for OTA distribution.

Start IPA Publisher

In the screenshot below you see the main window of IPA Publisher. You basically have only two options: 1) Configure your publish locations and 2) Give IPA Publisher a .ipa file. This can be done by dropping the file on the marked area in the main window, dragging the file on the dock icon (no matter if IPA Publisher is running or not) or for example by writing an Automator action or Finder service.

IPA Publisher Main Window

Configure a publish location

For the example, the first thing we want to do is configure a publish location. So just click on Manage Publish Locations and you get a simple dialog to configure your different publish locations. Click on + to add a new location and enter a name and the URL to access files in your Dropbox Public Folder. To get this URL go to the Dropbox website, select Get shareable link on your public folder and look in your browser’s address bar. The URL looks something like https://www.dropbox.com/s/’some token’. What you need is the ‘some token’ part of the URL. Shareable links to a Dropbox folder or file are of the form https://dl.dropbox.com/s/’some token’/'file’. So enter the URL https://dl.dropbox.com/s/’some token’ in the URL field in IPA Publisher and replace ‘some token’ with the token of your Dropbox Public Folder. You can leave the Base Directory and Custom HTML fields empty for now (I will explain later what they’re for).

IPA Publisher Manage Publish Locations

Once you’ve entered all the information as in the screenshot above, close the Manage Locations dialog by clicking Done.

Build And Archive

Use Xcode Build and Archive to create a new Ad-Hoc build of your application and switch to the Organizer when the build is done. Select the application and choose Share… and then Save to Disk… to save the .ipa file somewhere, e.g. your Documents folder as in the screenshots below.

Build and Archive Ad-Hoc Build

Share built application

Save the .ipa file to disk

Publish with IPA Publisher

Open your folder where you saved your .ipa file in the Finder and Drag and Drop the .ipa file to the designated area in the main window or to the application icon of IPA Publisher in your dock as shown in the next screenshot:

Drag the .ipa file to IPA Publisher

If you have multiple publish locations configured, IPA Publisher will ask you to which location you want to publish the .ipa file as shown in the next screenshot:

Choose a Publish Location

If you have only one publish location, IPA Publisher will automatically use this one location and not bother to ask you. And that’s it. As you can immediately see in the Finder window (and the screenshot below), IPA Publisher has created a .html, .plist, .mobileprovision and two .png files with the same name as your .ipa file.

Generated files by IPA Publisher

Now just put those files in your Dropbox Public Folder and navigate to the following website on your iOS device: https://dl.dropbox.com/s/’some token’/'the name of the .html file’.html and you should see a web site as in the screenshot below:

Generated Default website by IPA Publisher

By tapping on the two rows on the website you can now install the provisioning profile and the application over the air.

What just happened

IPA Publisher took the .ipa file you dropped on it’s application icon, extracted the Provisioning Profile, Icons and metadata from the Info.plist file and created all the necessary files to enable an OTA distribution of the Ad-Hoc build. Since you have only one publish location configured in IPA Publisher it uses this one as the default publish location and doesn’t bother to ask you for any additional information. If you have multiple publish locations defined, IPA Publisher opens a small popup when you drop an .ipa file on it’s icon and lets you choose the publish location you want to publish to.

Making the website fancier

As you probably see when you opened the generated website on your iOS device, the generated HTML is functional but very simple. If you want to provide your testers with a fancier website you can use the custom HTML field in the Manage Publish Locations window. To keep everything working with a custom HTML you need to make sure your custom HTML meets two mandatory (and three optional) requirement:

  1. Provide a link element for the provisioning profile in the form: <a href=”$profilelink”>Install Provisioning File</a>. IPA Publisher replaces the $profilelink placeholder with the correct link upon generation.
  2. Provide a link element for the application archive in the form: <a href=”itms-services://?action=download-manifest&url=$plistlink”>Install Application</a>. IPA Publisher replace the $plistlink placeholder with the correct link to the .plist file (which the devices uses to find and install the application) upon generation.
  3. (Optional) Place a placeholder named $title for the application name in the HTML. IPA Publisher replaces this with the value of the CFBundleDisplayName key in your application’s Info.plist.
  4. (Optional) Place a placeholder named $artworklink for the big application artwork in the HTML. IPA Publisher replaces this with a link to the iTunesArtwork file in the application bundle.
  5. (Optional) Place a placeholder named $iconlink for the small application icon in the HTML. IPA Publisher resizes the iTunesArtwork file to 57×57 pixels and replaces this placeholder with a link to the resized image.
You can place multiple instances of the placeholders in your HTML and IPA Publisher will replace all of them correctly.

Understand the Base Directory field

As you probably saw in the Manage Publish Locations window, you can also set a Base Directory for every Publish Location. To understand how the Base Directory works, suppose you want to organize your Ad-Hoc Builds in the following way in your Dropbox Public Folder:

Base Directory Layout

But configuring different Publish Locations for every one of those subfolders might be a little overkill, especially if, for example, you want to have one folder and publish location for one client and then separate subfolders the different apps for that client.

If you want to make a publish location with the URL for the parent folder (in the example the Dropbox Public Folder), the links in all the generated files in the subfolders would need to have the form https://dl.dropbox.com/s/’some token’/app1/app1.html. But if you try this, you will see that, even though the files are in subfolders, IPA Publisher will generate the URL https://dl.dropbox.com/s/’some token’/app1.html which is clearly not right.

That’s where the Base Directory comes into play. You set the base directory of the publish location to the folder the URL points to. So if https://dl.dropbox.com/s/’some token’ points to your Dropbox Public Folder which is located at /Users/me/Dropbox/Public you would put /Users/me/Dropbox/Public in the Base Directory field as in the screenshot below:

Publish Location with Base Directory

Then when you publish an .ipa file in a subfolder of that (e.g. /Users/me/Dropbox/Public/app1/app1.ipa), IPA Publisher compares the Base Directory with the path to the file. If the path to the file starts with the Base Directory, IPA Publisher removes the Base Directory from the path of the file and appends the remaining relative path to the URL upon generation. So in this example, IPA Publisher removes /Users/me/Dropbox/Public from the path to the .ipa, which leaves us with /app1/app1.ipa and leads to /app1 being appended to all generated URLs and everything working as excepted.

Alternatives

There are some great alternatives like Hockey (which I wrote about in a previous post), which works very well and the guys at Testflight, who have also done an amazing job. But I found that both are not quick and easy enough for me – Hockey needs you to include some code in your app Update: Sorry for the mistake, but Hockey does not need you to include code in your client app. The client part is optional if you want to have the automatic update notifications in the app. But you have to make sure that you do not ship the Hockey client framework with the App Store build of your app. And Testflight requires your users to register with them before they can install the test build.

Instead I switched to just using my Dropbox for sharing Ad-Hoc builds. One option is to use your Dropbox Public Folder, but another option is to switch to Dropbox’s new sharing site (which is described here) with which you can get a shareable link to any folder or file. The great thing about the second option is that you get a link with a unique, pretty much unguessable token for every file and folder you share.

So what I do is I have a folder in my Dropbox where I put all my Ad-Hoc builds, have subfolders for my different clients/projects and in those subfolders for every app of that client. I create Publish Locations for each of the client folders and set the path to that subfolder as the base directory of the publish location. Then I can just put a new app in a subfolder, publish the .ipa with IPA Publisher and send the slightly modified link to my client. (So the client gets a link https://dl.dropbox.com/s/theclientspecifictoken and then appends the app name to that link – e.g. https://dl.dropbox.com/s/theclientspecifictoken/app1/app1.html). Or you make a start page for the client in the base directory and then just link to the subpages in that file.

Let me know what you think

If you like what you read, head over to the Mac App Store and get IPA Publisher. And if you have any comments or suggestions how to make IPA Publisher better or more usable for iOS developers just drop me a comment, send me an email to martin (at) martinreichart (dot) com or just sent me a reply on twitter to martinr_vienna.
Easy distribution of Ad-Hoc iOS builds with Hockey
I recently came across a post on Twitter about somebody using Hockey for distributing Ad-Hoc builds to beta testers with iOS 4 or later. Hockey builds on the fact that in iOS 4 you can install Ad-Hoc builds easily from a website. It basically works like this:
  • Add the Hockey source code to your project
  • Tell Hockey where to find your Ad-Hoc builds on your PHP5-enabled webserver
  • Use Build and Archive in Xcode to build your Ad-Hoc Build
  • Use Xcode’s ‘Distribute for Enterprise’ feature to export the application build
  • Copy the application build to your webserver
  • Done

Step 1: Getting Hockey
You can get all the necessary parts you need for this right here on Github. The repository contains the necessary parts you need on the server as well as very simple client code and a small demo. Plus there are README files for the different parts.

Step 2: Setting up your webserver
The first step you need to do is set up your webserver. This is as easy as enabling PHP5 and copying the files in the server directory somewhere on your server.

Step 3: Adding Hockey to your project
The next thing you need to do is add Hockey to your project. Basically you can take all the code in the client directory (except the Beta Automatisation directory) and copy it into your project. One thing that’s important is that the Hockey code is not included in your Builds for the App Store. To do this, open the build settings of your target and select ‘All Configurations’. Then add the following to the setting ‘Preprocessor Macros Not Used In Precompiled Headers’: CONFIGURATION_$(CONFIGURATION)
This will add preprocessor macros so you can do the following in your code (assuming for example that your Ad-Hoc configuration is called AdHoc):

#ifdef CONFIGURATION_AdHoc
    NSLog("This will only be logged in Ad-Hoc builds");
#endif

or

#if defined(CONFIGURATION_AdHoc)
    NSLog("This will only be logged in Ad-Hoc builds");
#endif

You also might want to exclude the source files from Hockey in your App Store distribution build. To do this, switch to your App Store configuration in the build settings of your target and add a User-Defined Setting called EXCLUDED_SOURCE_FILE_NAMES. Then set it’s value so that all Hockey files are excluded (I renamed all hockey source files so they start with BWHockey and set the value of this setting to BWHockey*).

Step 4: Activating Hockey in your code:
Then just add the following to application:didFinishLaunchingWithOptions: in your AppDelegate:

#if defined(CONFIGURATION_AdHoc)
    [[BWHockeyController sharedHockeyController] setBetaURL: @"YourUrlPointToThePathWhereTheIndexPHPFileIsLocated"];
#endif

Of course you need to change the URL string accordingly. You also need to add a conditional header include:

#if defined(CONFIGURATION_AdHoc)
#import "BWHockeyController.h"
#endif

In my example, I only add the code in my Ad-Hoc builds by using the preprocessor macros we defined earlier.

Step 5: Building and distributing your application
Next, switch to your Ad-Hoc build configuration and use Xcode’s ‘Build and Archive‘ to create a build of your application. Then open the Organizer, go to the Archived Applications and select the application and build you just created. Click on ‘Share Application…’ and select ‘Distribute for Enterprise…’. In the following dialog enter ‘__URL__‘ in the URL field, type in a Title and fill out the rest if you want to. When you’re done, click ok and save the build to some location on your hard disk.

Connect to your webserver and go to the folder where you copied index.php in Step 2. In there create a subfolder named just like your application’s Bundle Identifier and copy the 2 files just Xcode exported for you (a .ipa and .plist file). That’s it.

Step 6: Accessing the application
Now your beta testers just need to navigate to the website and they see a list of all the applications that are found there (actually the index.php file searched for all .ipa and .plist files it can find). Then they just need to tap on an entry and can install the application right from Safari.

Step 7: Distributing updates
When you have an update for your beta app, change the bundle version in your Info.plist and repeat Step 5. The included index.php file can only handle one version of an app at a time, so you need to delete the old files before copying the new version. The next time your users start the application, they get a notification that there is a new version of the app available and they can install it right on the spot. Or they install it again via Safari.

Conclusion
The main advantage i see in using Hockey (or just wireless app distribution) is that it eliminates the need for beta testers to sync their devices with iTunes to get a new version of an app. No matter where they are, they can get the latest version of your app and start testing immediately.
Oh and although you ‘Distribute for Enterprise’ you don’t need to be a member of the iOS Enterprise Developer Program.

Links

Look out for your back – Pain-driven personal advice
This is my first post on the blog in quite a while but it gives a quick glance at the outcome of my last few weeks and months. Instead of some technical stuff I want to give all you developers (and all other people out there who spend most of their workday sitting) a personal advice.

As software developers we pretty much spend about 90% of our workday sitting in front of a computer or laptop – The remaining 10% are usually spent in short activities like going to the bathroom, getting water, a coffee or maybe a few steps during a phone call. Now, I’m not staying that every workday is like that but there are certainly many days in our life that look like that for 8-10 hours a day.

So what’s the problem with that? The problem starts when your lack of physical activity over such a long period of time causes your body and health to suffer. I personally experienced this about 4 1/2 years ago when I started feeling pain in my lower back after sitting for a long time or after doing some exhausting sport (basically anything that strained my back). At first I didn’t pay too much attention to this and dismissed it as nothing serious – nothing a relaxing massage couldn’t fix.

But then 3 months after that I woke up one morning and simply couldn’t get up because of the blinding pain in my back during even the slightest movement. After having an MRI I was diagnosed with a herniated vertebral disc. Instead of having surgery (which is nowadays done very rarely with such an injury) my doctors suggested going with “conservative therapy” – meaning pain medicine, physical therapy, and patience and after about 4 months I was able to walk again rather painless.

Now 4 years after that I started feeling a certain tension in my back again and all the memories came screaming back to me (i think becoming sort of a hypochondriac comes naturally with such an injury). What’s even worse is that I don’t really have back pain, but I feel that something is not quite alright and in addition I occasionally have a weird feeling (sort of like a tingling) in my left foot. My doctors say that it’s nothing like what I had 4 years ago but there is definitely some kind of irritation of the nerves. My therapy advice so far: Try to sit less!

As a developer your first thought may be “Good one”, but there are definitely a lot of things we can do to take care of our back during a busy workday, so here’s a few things I recommend and will try to personally stick to:

  • Make breaks: Try to make short breaks at least every 25 minutes to get up, walk around a bit and straighten and stretch your back and legs. If you’re anything like me, you tend to forget to do this regularly. That’s why I use a Mac application called Time Out by Dejal which let’s you set timers to remind you and covers your screen with a reminder to take a break. In conjunction I sometimes work according to the Pomodoro Technique which recommends working in 25 minute increments (called pomodori) and making a 5 minute break between two pomodori to relax and refocus
  • Get a really good chair: I currently have a really basic leather office chair, which I thought was pretty decent. But when my back problems started again I went to a shop which is specialized in ergonomically great chairs and tried a couple of them. And thanks to a recommendation from a friend I tried a chair by Varièr (former Stokke) and after sitting on it for a few minutes I noticed how much difference there actually is in chairs.
    And do yourself a favor and don’t care about the price at first – a good chair which supports your back is more important than thinking about 200 bucks difference for a chair you’re probably going to have 10 years.
  • Drink enough during the day: This is important because your spinal discs are basically filled with water to help absorb pressure. Staying well hydrated helps your spinal discs properly refill during your sleep.
  • Get some regular exercise: Try to regularly do some kind of sport for your back and abdominal muscles. Those two regions are especially important because they help stabilize the whole spine. Personally I have found Pilates to be very helpful. There are different forms of Pilates – some more Aerobic-style and some very relaxed. I would absolutely recommend the second type, but depending on where you live it might be quite hard to find an appropriate instructor (and you should really do this with a professional instructor and not some kind of book or video, because only an instructor can give you advice on your individual needs)
  • Listen to your body: If you’re feeling pain, your body tries to tell you something; too much stress, too little exercise, bad posture, … Listen to these signs and make changes, because sooner or later this is gonna fall on your head and you’re just gonna pay with your health.

Oh and one more thing: With a lot of health-related problems we usually tend to think that certain things won’t happen to us, because we’re young. But believe me: Back problems do not fall into this category!
So take care of yourself before you even get problems with your back!

WWDC and going to the Apple Company Store
Jeff LaMarche put up a questionnaire for everybody who’s interested in going down to Apple’s Company Store in Cupertino on Sunday, June 6th just before WWDC. The idea is to either find enough people with cars to take everybody down or to rent a bus or van or something. Great idea and an awesome opportunity to meet a lot of developers already before WWDC. Big thanks to Jeff!
New challenges
One of the reasons I became a freelance software developer was that it gives you the chance to have new projects and challenges to work on at a regular basis. You usually don’t have the risk to stay in a project for years or even decades, but instead constantly see new fields and technologies to work in and with and often have to grow into a new team and work with new people which i think helps you become a better team person.

Since spring last year I have dedicated a lot of my time to one specific Java project – a rather large software project in a big enterprise which has already been going for a few years. The main reason I started working in this project wasn’t necessarily the technology or even the business context but the way the team worked – the project tried to employ agile practices a lot and was actually quite successful in achieving this in such a big enterprise.

After around a year in the project now I have decided that i want to move on to new challenges in my professional career and decided to leave this project by summer. I have been struggling with this decision for a couple of weeks now since I made some very good friends on the team. But in the end I think it’s the better choice for me to leave the project.

So starting this summer I will be enjoying cocktails on my balcony and the (hopefully) great weather in Vienna. Well, not quite. I’ve been doing quite a bit of iPhone and Mac development over the last 2 years or so – always as side projects to my main Java consulting job either as a freelance consultant or together with the folks at Gravity Applications. After a lot of thought I decided to partner up with a good friend of mine from Gravity Applications and concentrate solely on development for the Mac, iPhone and now the iPad. By dropping all of my Java consulting work I will be able to put more effort into Gravity Applications to achieve more great things for our applications. We also plan on working together as a team to do more consulting for the iPhone and iPad here in Vienna and around.

I’m really excited about this since it’s a pretty big change for me and dropping all of my “safe” Java projects feels quite a bit like jumping into cold water. But I’m pretty sure it will be totally worth it…

Making progress on jSparkle
About a month ago I announced that I decided to work on a Java application updating framework called jSparkle based on the ideas behind Sparkle – a popular updating framework for Mac applications. After having a bit of time I wanted to give you all a quick update on how far I am with jSparkle and also about some of the problems I still have on my ‘to solve’ list.

Again, what is jSparkle?

The idea behind jSparkle is to have a very easy to use Java application updating framework, which is extremely easy to integrate into existing applications. jSparkle was inspired by the great Sparkle framework for the Mac.
Integrating Sparkle into a Mac application is as simple as dropping in a library, configuring a few settings and that’s it. Sparkle automatically takes care about checking for new updates for your application, presenting this to the user, downloading the update and updating your application.
The biggest goal for jSparkle is to make it just as easy.

First steps

My first idea for jSparkle was to actually use the same mechanisms as Sparkle – Appcasts. These are simple RSS feeds which contain information about updates for the application and the address of the updated application archive itself.
But since Java applications are a bit more complicated than Mac applications from a deployment point of view (a Mac application usually consists of just one application archive which Java applications are usually split into a lot of parts like different 3rd party libraries, resources etc and at least in the Java enterprise world are a lot bigger than the typical Mac application) I was not very happy with that approach. Downloading the whole application is sometimes not a feasible option (I currently work in a Java project where the application is 160MB).

So how does it actually work?

The idea for jSparkle arose because I’m currently dealing with the exact same topic in a Java project I’m working in. And a few days ago me and my colleagues worked out a solution that I’m also going to use for jSparkle. It’s built all around MD5 checksums and basic comparison of those.
With every update of the application, a checksum file is created which contains the MD5 checksums of all files of the application. jSparkle compares the checksums of all local files of the application against the checksum of the now up-to-date server version. When a difference is found, a new version is available and jSparkle knows exactly which files it needs to update (the ones with a different checksum).

The big advantage of this is that jSparkle can determine exactly which files have changed and needs to download only those files which results in a lot less used bandwidth. It also means that jSparkle can determine when the user has somehow tampered with the application (i.e. deleted important files or modified things that should not be modified) and can automatically update the necessary files.

Another advantage is that jSparkle does not need to put any temporary data anywhere on the computer since all the information it needs to determine the current version are right there in the installation directory of the application. This is particularly important if your application is running in a restricted environment where the user does not have sufficient permission to write files, but you still want to inform him when there is a new version of your application (and maybe even inhibit him from using the app any further if there is a new version).

Dropping App Casts?

Basically it’s not necessary to use App Casts anymore with this approach. But I think they provide some very interesting additional information for the user like release notes and therefore jSparkle will use App Casts – they’re just a bit different than the ones from the original Sparkle framework.

Yay it works…

I’ll make this short: The very core of jSparkle with the check for updates, downloading changes and verifying everything works. It’s as simple as instantiating a jSparkle class and giving it your application’s identifier and the URL to the Appcast. jSparkle then automatically checks the Appcast for new updates for your application and reads the necessary checksum information and presents a dialog to the user if there are updates, shows him the release notes and total size of all the updates and let’s him start the download of the updates.

The dialog which shows all this is currently SWT-based, but in the future it will support all the major UI frameworks available in Java. jSparkle then downloads all the updates to a (configurable) temporary location and verifies the integrity of the downloaded files (again via the checksum information). The actual update of the application is another story…

So how do we update this thing?

Updating the application is actually not so trivial, because it can be that some files are locked by the Java virtual machine and therefore can’t be deleted or replaced. So my current solution for this looks roughly like this:

  • Copy jSparkle to a temporary location
  • Start jSparkle from the temporary location and quit the virtual machine that is running the application
  • Perform the update from this separate virtual machine avoiding any locks on any files
  • Start the original app and quit the update virtual machine
  • In theory this should work just fine – but this is something I have yet to do. So we’ll see if this actually holds in the future.

    One more thing…

    Just as it took me longer to finally write this blog post, it’s also taking longer for jSparkle to advance. But the last two weeks have actually cleared a lot of open questions about how to do certain things in jSparkle and this gives me a lot of confidence that jSparkle will be very nice to use and way superior than stuff like Eclipse Update Sites or Eclipse P2.

    Another positive thing the last two weeks (or rather last few days) brought is that I now have a partner to work on jSparkle with me (yes I mean you Klaus!) and we already have a few more ideas for jSparkle to make it become a really nice updating framework for Java (Continuous Build Integration, Automatic Deployment to give you a general idea of what we’re talking about).

    I really hope that the next update about jSparkle comes a bit earlier than this one and will very much try to not keep you waiting too long. And I will also show you a few samples and code excerpts of jSparkle with the next update. Until then I’ll be glad to hear about feedback from you…

    Updating Java Applications
    Updating your application is one of the most important things you need to have a good solution for before you deploy the first version of your app. Being able to update your application once it’s out and in use is crucial to being able to fix bugs or bring new features to users of your application. This post will talk about what options you have in the Java community at the moment and what I think of these options. I will only be talking about rich/fat client desktop applications in this post and not about web applications or the like.

    What is there in the Java world ?

    In Java there are actually quite a few solutions for this kind of task. There is the option to use something like Java Webstart where you have your users open a link in their browser to download and start your application. Before starting your application, Webstart checks if there are updates and downloads them if so.
    If you build applications based on Eclipse’s RCP you have the options to use the “old” Eclipse Update Site mechanism or the “new” one based on P2 Repositories. Both provide sort of a repository where you can have multiple packages in different versions with the repository content described with XML files.

    Why do these options suck ?

    All of those technologies have major drawbacks in my opinion:

    • Using Webstart is strange, because the user doesn’t directly start your application but instead uses some other tool to access it only to make sure the app gets updated. Also there is no nice way to make sure the app gets updated when the user starts your app directly.
    • Eclipse Update Sites and P2 are both rather complex in their configuration and the code to communicate with an Update Site or a P2 repository is far from simple (actually it’s quite horrible).
    • With both solutions the user suddenly sees a bunch of files being checked/updated during an update; all the libraries you use and multiple jars you have your code spread across. This doesn’t really make sense to the user – he should only see your application as a whole and “updating any subpart of your application’s files” just means “updating your application” for the user.
    • This is something every application has to deal with. So this should be just as simple as printing “Hello World” on the screen.

    Seeing how easy life could be

    On the Mac side, there is a really elegant solution that’s used in almost any up-to-date application out there and which works really really nice and simple: The Sparkle framework.
    Sparkle is based on RSS feeds (called Appcasts in Sparkle) and simple file downloads. You add the framework to your application, tell it where to find the Appcast which publishes updates for your application and you’re done. Sparkle takes care of checking for updates, notifying the user when there is an update available, downloading it as well as replacing and restarting your app.
    The Appcast itself also is really simple. For every update you have, you provide a name, a publishing date, a link to release notes and a link to the updated application file.

    Of course it’s a bit simpler because on the Mac applications are always in a single bundle, meaning you only have to download and update a single file. A Java application (and especially a Eclipse RCP application) consists of many files. But this doesn’t justify the fact that the existing Java solutions are that much more complicated.

    Introducing jSparkle

    Because of this I decided to tackle this problem and build a Java framework that’s as simple as Sparkle on the Mac, but still powerful enough to do the things that Webstart, Eclipse Update Sites and P2 provide. I decided to call it jSparkle to honor the creators of the Sparkle framework because I want to build on the concepts behind Sparkle.

    The goal of jSparkle is to provide a complete Java application update framework which provides developers with a simple solution to deliver updates for their applications. It will provide the developer with a very minimalistic API to configure the update mechanism and everything else will be dealt with automatically by jSparkle, including all the UI that needs to be presented to the user. jSparkle will be designed with the guideline to be as simple as Sparkle on the Mac, but as powerful as P2 for Eclipse without putting more burden on the developer.

    I will provide jSparkle as an Open Source framework available and free of charge for everyone and there will be no limitations regarding where and how you use jSparkle or if and how you modify it for your specific needs. As soon as it’s in an actual usable form I will also put it on a public repository so everybody can play with it, fork it, give feedback and help improve this to be a great solution.

    A kind of timeline…

    Now, I just started yesterday because I wanted to try to things and this changed into a project idea pretty quickly. There is not that much code there yet, but this should change relatively quickly and I want to post a first version of jSparkle some time in March. Long before that I’ll try to post a few examples of the jSparkle API as soon as possible so you can get an idea of how simple it will be to use jSparkle as a developer.

    If you have any things you think should be in a great update framework or just want to give me feedback about the idea, feel free to post a comment or send me an email.

    Getting iPhone Push Notifications to work
    I’m currently working on a small iPhone application which will be my first app to use Apple’s Push Notification Service.

    Since I want to keep the app small and simple I decided to use one of the third-party providers for Push Notifications and decided to go with Urban Airship. Setting up everything with Urban Airship was a breeze and literally done in seconds. Create an application with Urban Airship, create the SSL certificate for the Push Notifications in Apple’s iPhone Developer Program Portal, upload it to Urban Airship, done!

    The API for Urban Airship is amazingly simple and my server code to do everything I want is just a few lines long. But before I was ready to use Urban Airship’s API I did spend some time to just enable Push Notifications in the app.

    Setting up push notifications

    Basically setting up your app to receive push notifications is really simple. You have to create an App ID (without wildcards), create a new Provisioning Profile for that App ID and enable push notifications for that Provisioning Profile. When you have the Provisioning Profile, just have to add it to Xcode, change the Bundle Identifier of your application to match the App ID, and choose the new Provisioning Profile as the Code Signing Identity in your application target.

    After you have everything configured, you can implement the code to register the device to receive push notifications for your app, which is really adding 1 line of code and two delegate methods, which get called when the registration succeeds or fails.

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

    It should work, but…

    And this is exactly where I spent most of my time to get Push notifications to work. I had everything configured, double and triple checked everything, started my app and tried to register for notifications and….it failed. The error I got was something that a lot of people seem to stumble upon:

    Failed to register for remote notificaitons. Error: Error Domain=NSCocoaErrorDomain Code=3000 UserInfo=0x2782a0 "no valid 'aps-environment' entitlement string found for application"

    At first I thought that I got the App ID wrong or Xcode messed something up with the Provisioning Profile. But after checking that multiple times I thought I’d try to recreate the Provisioning Profile and start over. But that didn’t help at all. Same error, no difference. Some blogs recommend to create an entitlements file and add and ‘aps-environment’ variable. I was skeptical about this solution, but after many failed attempts I thought I mght as well try. But no surprise – it didn’t work.

    The solution

    The problem was actually one of the first things I suspected: Xcode did sign the application with the wrong profile. The tricky part was that when I looked at the Build Configurations by clicking on the Build Target everything looked fine. But when I looked at the Build Configurations by going to the Project Info I saw that Xcode had another Code Signing Identity set, which didn’t have Push Notifications enabled.

    After all this i realized that there would have been a much easier way to find this: I could have looked at the Build Results and check what Profile was used to sign the application. So if you have problems getting Push notifications to work always check the Build Results first to see if the application is signed correctly.

    After that was done, implementing Push notifications was really easy thanks to the simple and well-documented API of Urban Airship.

    So if you want Push Notifications in your app but don’t want to mess around with a server implementation to interact with Apple’s Push Notification Service, check out Urban Airship. It can really save you a lot of time!

    The Future of finding the best iPhone apps
    There’s a new article on Gravity Applications’ blog about the future of finding the best apps for your iPhone/iPod Touch and the story behind Appfinder. I’ve been working on Appfinder in the last few months, so if you want to get more insights into how it became an iPhone app be sure to read this post.
    Great way to help Haiti and get great software: Indie + Relief
    Indie+Relief is a site listing Mac and iPhone applications whose developers decided to donate all the money from sales today to Haiti – every developer choses where the money from his sales will go to. Great way to get a bunch of software and do something good. If you don’t want any new software, i suggest you donate for help in Haiti anyway!