使用MonoTouch制作自我更新的iOS应用程序有哪些选择?

时间:2011-10-04 10:30:07

标签: ios deployment xamarin.ios auto-update ad-hoc-distribution

我正在尝试制作一个iPad / iPhone应用程序(使用MonoTouch),首先检查当前版本与自定义Web服务报告的最新版本。如果应用程序已过期,则应从Web服务下载新版本的二进制文件并替换当前版本。

该应用程序将通过ad-hoc或通过企业部署进行分发,因此不受Apple验证或AppStore版本控制系统的限制。

我正在考虑制作两个应用程序,一个引导程序和真正的应用程序。在Windows下,引导程序将使用简单的文件操作来替换真正的应用程序,但在iOS下我不太确定这是可能的,如果可能的话,我不知道该怎么做。

所以,问题是:这是使用MonoTouch for iOS制作自我更新应用程序的“正确”方法

感谢。


更新

好像我有这个工作,至少在模拟器中。

基本思想是在引导程序中实现最小化,如Main()方法和AppDelegate,然后使用反射从位于应用程序包外部的二进制文件加载导航控制器和其他所有内容,接受自我更新操作。

这是引导程序代码:

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;
        }
    }
}

真正的应用程序代码:

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);
        }
    }
}

在模拟器中显示“工作!”标签,我只希望在真实设备上运行。


更新2

以上方法仅适用于模拟器,在iOS设备上它会在Assembly.Load上崩溃。

2 个答案:

答案 0 :(得分:6)

您不能这样做 - 至少不会替换可执行二进制文件,因为包已签名(如果位于应用程序包之外,更新数据不会成为问题)。

但是你仍然可以(一个正确的方式):

  • 检查更新(例如使用网络服务);和
  • 通过提供更新链接,帮助用户更新(例如通知他们)。

这可以手动完成(即使用您自己的代码)或使用TestFlight SDK(查找应用内更新)。

答案 1 :(得分:2)

Poupou的答案几乎涵盖了它。

但我想补充一点,您仍然可以远程配置应用功能。例如,应用程序可以检查服务器上的配置文件,然后根据该文件允许或拒绝访问某些功能。

这当然意味着必须已包含用于计划发布的任何功能。

它不会涵盖所有用例,但它允许您在某个特定功能之前保留某个功能,直到每个用户都安装了最新的二进制文件,这样每个人都可以同时访问该功能。

另一种方法是将尽可能多的功能转移到脚本中,这些脚本可以随时进行交换或增强。但是,要以这种方式开始,还需要做更多的工作。

最后,您可以实施一种机制,检查新版本是否可用并停用大多数应用功能(可能在宽限期之后),以强制用户升级到新版本。