3

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

该应用程序将通过临时或通过企业部署分发,因此它不受 Apple 的验证或 AppStore 的版本控制系统的约束。

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

那么,问题来了:使用 MonoTouch for iOS 制作自更新应用程序的“正确”方式是什么?

谢谢。


更新

似乎我已经完成了这项工作,至少在模拟器中。

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

这是引导程序代码:

主文件

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

真实应用代码:

导航控制器.cs

namespace TheApp
{
    [Register("NavigationController")]
    public class NavigationController : UINavigationController
    {
        // Connect view stuff
        // ...

        // Constructors
        // ...

        void Initialize ()
        {   
            this.PushViewController(new HomeController(), true);
        }
    }
}

家庭控制器.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 上崩溃。

4

2 回答 2

6

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

但是你仍然可以做(正确方法):

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

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

于 2011-10-04T12:04:38.443 回答
2

Poupou的回答几乎涵盖了它。

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

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

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

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

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

于 2011-10-04T13:04:22.423 回答