3

現在のバージョンとカスタムWebサービスによって報告された最新バージョンをチェックすることから始まるiPad/iPhoneアプリケーション(MonoTouchを使用)を作成しようとしています。アプリケーションが古くなっている場合は、Webサービスから新しいバージョンのバイナリをダウンロードして、現在のバイナリを置き換える必要があります。

アプリケーションはアドホックまたはエンタープライズ展開を介して配布されるため、Appleの検証やAppStoreのバージョン管理システムの対象にはなりません。

ブートストラッパーと実際のアプリケーションの2つのアプリケーションを作成することを考えていました。Windowsでは、ブートストラッパーは単純なファイル操作を使用して実際のアプリケーションを置き換えますが、iOSでは、これが可能かどうかはわかりません。可能であれば、その方法もわかりません。

それで、ここに質問があります:iOS用のMonoTouchで自己更新アプリケーションを作成するための「正しい」方法はどれですか?

ありがとう。


アップデート

少なくともシミュレーターでは、これが機能しているようです。

基本的な考え方は、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);
        }
    }
}

シミュレーターでは、「Working!」と表示されます。ラベル、私は実際のデバイスでも機能したいと思っています。


更新2

上記のアプローチはシミュレーターでのみ機能し、iOSデバイスではAssembly.Loadでクラッシュします。

4

2 に答える 2

6

これを行うことはできません-パッケージが署名されているため、少なくとも実行可能バイナリを置き換えないでください(アプリケーションバンドルの外部にある場合、データの更新は問題になりません)。

ただし、それでも(正しい方法で)実行できます

  • 更新をチェックします(たとえば、Webサービスを使用します)。と
  • 更新へのリンクを提供することにより、ユーザーが更新するのを支援します(たとえば、ユーザーに通知します)。

これは、手動で(つまり、独自のコードで)、またはTestFlight SDKを使用して(アプリ内更新を探す)実行できます。

于 2011-10-04T12:04:38.443 に答える
2

Poupouの答えはほとんどそれをカバーしています。

ただし、アプリの機能をリモートで構成できる可能性があることを付け加えておきます。たとえば、アプリはサーバー上の構成ファイルをチェックし、そのファイルに応じて一部の機能へのアクセスを許可または拒否できます。

これはもちろん、スケジュールされたリリースを対象とした機能がすでに含まれている必要があることを意味します。

すべてのユースケースを網羅しているわけではありませんが、たとえば、すべてのユーザーが最新のバイナリをインストールするまで特定の機能を保留して、すべてのユーザーが同時にその機能にアクセスできるようにすることができます。

もう1つのアプローチは、可能な限り多くの機能をスクリプトにシフトすることです。スクリプトはいつでも交換または拡張できます。ただし、この方法で開始するには、さらに多くの作業が必要になります。

最後に、新しいバージョンが利用可能かどうかをチェックし、ほとんどのアプリ機能を非アクティブ化するメカニズムを実装して(おそらく猶予期間後)、ユーザーに新しいバージョンへのアップグレードを強制することができます。

于 2011-10-04T13:04:22.423 に答える