I am trying to make an iPad/iPhone application (with MonoTouch) which starts by checking the current version versus the latest version reported by a custom web service. If the application is out of date it should download the binaries of the new version from the web service and replace the current one.
The application would be distributed either ad-hoc or via enterprise deployment, so it's not subject to Apple's validation or to AppStore's versioning system.
I was thinking of making two applications, a bootstrapper and the real application. Under Windows, the bootstrapper would use simple file operations to replace the real application but under iOS I'm not so sure this is possible and, if possible, I don't know how to do it.
So, here's the question: which is the "right" way to make a self-updating application with MonoTouch for iOS?
Thanks.
UPDATE
Seems like I've got this working, at least in simulator.
The basic idea is to implement a bare minimum in the bootstrapper, like the Main() method, and the AppDelegate, then use reflection to load the Navigation controller and everything else from a binary file located outside the application bundle, which would be subject to self-update operations.
Here's the bootstrapper code:
Main.cs
namespace Bootstrapper
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args,null,"AppDelegate");
}
}
}
AppDelegate.cs
namespace Bootstrapper
{
[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
// Connect window and navigationController stuff
// ...
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
Assembly asm = Assembly.LoadFile(@"/Users/sorincom/Projects/SelfUpdate/TheApp/bin/Debug/TheApp.dll");
navigationController = (UINavigationController)Activator.CreateInstance(asm.GetType("TheApp.NavigationController"));
window.AddSubview (navigationController.View);
window.MakeKeyAndVisible ();
return true;
}
}
}
Real application code:
NavigationController.cs
namespace TheApp
{
[Register("NavigationController")]
public class NavigationController : UINavigationController
{
// Connect view stuff
// ...
// Constructors
// ...
void Initialize ()
{
this.PushViewController(new HomeController(), true);
}
}
}
HomeController.cs
namespace TheApp
{
[Register("HomeController")]
public class HomeController : UIViewController
{
// Connect view stuff
// ...
// Constructors
// ...
void Initialize ()
{
View = new UIView();
var label = new UILabel();
label.Frame = new System.Drawing.RectangleF(50f, 50f, 200f, 200f);
label.Text = "Working!";
View.AddSubview(label);
}
}
}
In the simulator it displays the "Working!" label, i just hope to function on the real device as well.
UPDATE 2
The above approach works only in simulator, on iOS device it crashes on Assembly.Load.