web-dev-qa-db-ja.com

iPhoneユーザーにアプリケーションのアップグレードを強制できますか?

ITunes Storeでアプリケーションの新しいバージョンが利用可能になったら、ユーザーに強制的にアップグレードさせることはできますか?

私は現在、アプリケーションに取り組んでいます。ただし、新しいバージョンをアップロードするたびにアップグレードを強制します。これは、アップグレードの機能が増え、以前のバージョンを破棄するためです。 iPhoneではデフォルトでこれが可能ですか、それとも現在のバージョンをチェックしてストアと比較するために独自の実装を作成する必要がありますか?

46
Nareshkumar

システムがアプリケーションの更新を処理する唯一の方法は、標準AppStoreアプリケーションで更新が利用可能であることをユーザーに促すことです。
また、スタンドアロンアプリケーションは利用可能な更新を認識しないため、アプリケーションが現在のバージョンが有効かどうかを確認できるWebサービスを実装する必要があります。
そして、これがAppleアプリケーションのルールに準拠しているかどうかはわかりません。たとえば、プルーフリンクは見つかりません)アプリケーションの試用版をアップロードできません。

* EDIT *この答えはもはや真実ではありません。現在の真実については、他の賛成の回答をご覧ください。

7
Vladimir

ITunes Webサービスからバージョンを取得し、現在のバージョンと比較することで、この機能を実行しました。以下は私のコードです

        NSString *version = @"";
        NSURL *url = [NSURL URLWithString:@"http://iTunes.Apple.com/lookup?id=<Your app ID>"];
        versionRequest = [ASIFormDataRequest requestWithURL:url];
        [versionRequest setRequestMethod:@"GET"];
        [versionRequest setDelegate:self];
        [versionRequest setTimeOutSeconds:150];
        [versionRequest addRequestHeader:@"Content-Type" value:@"application/json"]; 
        [versionRequest startSynchronous];

        //Response string of our REST call
        NSString* jsonResponseString = [versionRequest responseString];

        NSDictionary *loginAuthenticationResponse = [jsonResponseString objectFromJSONString];

        NSArray *configData = [loginAuthenticationResponse valueForKey:@"results"];

        for (id config in configData) 
        {
            version = [config valueForKey:@"version"];
        }
   //Check your version with the version in app store
        if (![version isEqualToString:[itsUserDefaults objectForKey:@"version"]]) 
        {
            ProAlertView *createUserResponseAlert = [[ProAlertView alloc] initWithTitle:@"New Version!!" message: @"A new version of app is available to download" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles: @"Download", nil];
        [createUserResponseAlert show]; 
        [createUserResponseAlert release];
        }

ITunesリンクにアプリIDを入力すると、以下のコードが表示されます。

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    // the user clicked one of the OK/Cancel buttons
    if (buttonIndex == 1)
    {
        NSString *iTunesLink = @"itms-apps://phobos.Apple.com/WebObjects/MZStore.woa/wa/viewSoftwareUpdate?id=<appid>&mt=8";
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
    }
}

注:Webサービスを呼び出すには、JSONKitフレームワークとASIHttpフレームワークが必要です。

37
Dilip Rajkumar

アプリに更新が必要かどうかを検出し、更新が利用可能であることをユーザーに警告するなどのカスタムアクションを実行できます。更新が利用可能であることを検出するコードスニペットを次に示します。

-(BOOL) needsUpdate{
    NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString* appID = infoDictionary[@"CFBundleIdentifier"];
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://iTunes.Apple.com/lookup?bundleId=%@", appID]];
    NSData* data = [NSData dataWithContentsOfURL:url];
    NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    if ([lookup[@"resultCount"] integerValue] == 1){
        NSString* appStoreVersion = lookup[@"results"][0][@"version"];
        NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
        if (![appStoreVersion isEqualToString:currentVersion]){
            NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
            return YES;
        }
    }
    return NO;
}
22
datinc

どうしても必要な場合は、ユーザーがApp Storeから最新バージョンを入手できるようにApp Storeを起動できます。これをオプションにするか、少なくともダイアログを最初に提示することをお勧めします。

// iTunesLink should be your applications link
NSString *iTunesLink = @"http://phobos.Apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284417350&mt=8";


[[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
18
BadPirate

この質問はもともと7年前に投稿されたもので、いくつかの回答は関連性がありますが、ここでは最新のアプローチを示します。

https://github.com/ArtSabintsev/Siren Swift 3と互換性があり、CocoapodsまたはCarthageと共にインストールできます。

CocoaPods、Swift 3サポート:

pod 'Siren'

カルタゴ:

github "ArtSabintsev/Siren"

12

強制アップグレードのシステムは、そのアプリケーションの外部の何かに依存するすべてのアプリケーションの一部である必要があります。両方AppleとGoogleは、アプリが外部の何かを使用する場合、その外部APIは永遠に存続し、変更することはない、などなどと主張しますが、それは単に非現実的です。アプリが依存するサービスは変更される可能性があります[〜#〜] [〜#〜]アプリがチェックして確認する方法である必要があります機能を制限し、ユーザーに最新バージョンを取得するようプロンプトを表示する必要がある場合は、不可解に失敗します。

これはAppleとGoogleが提供するものですが、いくつかのゲーム以外のすべてのアプリがこれをビルドする必要があるわけではありません...

この問題の解決策を作成するためにRailsベースのオープンソース(Apache 2.0)プロジェクトを開始しました。これはApplication- [Ctrl]と呼ばれ、非常に進行中の作業ですが、自由に使えるようになったら、すべてのアプリ開発者に非常に合理的なレベルの無料サービスを提供し、もちろんすべての企業が常に独自の展開を起動できます。

GitHubにあります: https://github.com/SlalomDigital/ApplicationCtrl

この問題の解決に貢献してください!

7
Aaron Cooley

自動化された方法はありません。手動で何かを書く必要があります。

6
kubi

ビジネス/設計計画に「ユーザーを強制する」というフレーズを含めないでください。人々に何かをさせると怒ります。ある朝、気の利いた小さなアプリを急いで開いたユーザーが、必要なアプリを使用する前にアップグレードを強制していることに気づいたとします。彼がEdgeを使用してダウンロードしなければならない荒野で突き出ていると想像してください。彼は幸せではありません。

この計画を十分に長く守った場合、アップグレードの1つで目立ったバグが発生します。ユーザーにバグのあるバージョンの使用を強制すると、反抗します。

これは必然的に機能の増大を意味するため、ソフトウェアの新しいバージョンを説明するために使用される「その他の機能」を見るたびに、私は経験にうんざりするように条件付けられてきました。デザイナーは、1つのアプリがすべてを実行するまで、より多くの機能をアプリに移植し続ける傾向があります。これはiPhoneのようなプラットフォームでは特に危険です。1つのアプリで多くのことを行うと、アプリのインターフェイスと応答性が急速に圧倒されます。

Edit01:私のコメントはこちら ユーザーがアップグレード料金を支払った後にアプリケーションを更新する方法 もあなたの計画に関連しているかもしれません。アップグレードデザインでAppleが収益ループから外れると、それはスターターではありません。

更新:

以下のコメントに基づいて明確にするだけです。はい、時々ユーザーにアップグレードを要求する必要があります。ただし、それはdesigningアプリstartから、開発者が新しいバージョンをリリースするたびにユーザーに強制的にアップグレードさせます。

このような設計は、ユーザーではなく開発者の生活を楽にすることを目的としています。ユーザーが求めていない、またはおそらく望まない利益のためにアップグレードに時間を費やす必要があるたびに、顧客から時間とリソースを奪っています。開発者からユーザーへの時間と労力をオフロードする設計は、人々が最終的に自分の利益のためにソフトウェアを購入するため、悪い設計です。そのメリットを減らすと、ソフトウェアの最終的な収益性が低下します。

したがって、絶対に技術的に必要でない限り、ユーザーが望まないことをユーザーに強制するソフトウェアを設計するデザイナーはいません。これはもちろん経験則ですが、非常に良い方法です。

5
TechZen

App Storeへの私のアプリの更新は、まさにこの理由で拒否されました。インストールされているバージョンを現在のリリースと照合する機能を追加し、サポートされていないバージョンの場合は強制的に更新します。

Appleはこれを拒否しました。

それでは、デザインボードに戻りましょう!

5
Steig

他の回答は、強制更新機能を自分で実装する必要があることを示しています。それは本当に残念です、そうではなかったことを望みます。 iOSアプリケーションの最初の更新は明日リリースされますが、幸いなことに、アプリに変更を加えただけなので、問題はありません。ただし、最終的にWebサービスの構造を変更する場合、サーバーが各バージョンのアプリをサポートする必要がないように、更新を強制できるようにすることは非常に便利です。

ただし、強制更新に代わるものがあり、このスレッドでは言及されていないようです。データを生成するすべてのWebサービス呼び出しでスキーマをデータにアタッチし、アプリでデータをデシリアライズする方法をアプリに指示することができます。これにより、アプリのデシリアライゼーションを中断することなく、get-requestsによって生成されたデータの構造を変更できます。もちろん、これはあなたが書いたインタープリター自体は変わらないことを前提としていますが、それが成熟したときに行うのはある程度合理的な仮定です。

投稿リクエストは、相互作用を通じて「スキーマ化」されます。これにより、すべてのポストリクエストを行う前に、最新のWebサービスを呼び出す方法についての指示を求めることになります。そのために添付されたスキーマを使用して指示を処理してから、実際にWebサービスを呼び出します。基本的に、これはすべての投稿リクエストが2つのリクエストを必要とすることを意味しますが、それは大丈夫です。

ただし、強制更新またはスキーマ解釈を実装する場合でも、機能はApp Storeに到達した1日目からアプリに存在する必要があります。そうでなければ、あなたは同じ混乱にいます。 Apple開発者に強制更新を実装した場合、この複雑さは不要です。強制更新が存在する場合、スキーマの解釈は依然として使いやすさの向上になります。しかし、Appleは強制的に更新しませんでした。少なくともそれがあれば、アプリがリリースされた後に自分自身のアンチブレーク更新手段を導入できるからです。

4

将来は誰でもこんにちは。私はこのチュートリアルを見つけました。

http://codewithchris.com/tutorial-how-to-implement-in-app-update-functionality-in-your-iphoneipad-app/

編集(コードは次のようになります):

// Try to get version 
NSString *versionNumber = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

NSURL *updateUrl = [NSURL URLWithString:@"http://yourdomain.com/yourupdatefile.xml"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:updateUrl
                                            cachePolicy:NSURLCacheStorageNotAllowed
                                        timeoutInterval:20.0];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
                                     returningResponse:&response
                                                 error:&error];
// Check no error, then parse data
if (error == nil)
{
    // Parse response into a dictionary
    NSPropertyListFormat format;
    NSString *errorStr = nil;
    NSDictionary *dictionary = [NSPropertyListSerialization propertyListFromData:data
                                                                mutabilityOption:NSPropertyListImmutable
                                                                          format:&format
                                                                errorDescription:&errorStr];        
    if (errorStr == nil)
    {
        @try {

            // Try to see if the current app version exists in the update xml
            NSString *itunesUrl = [dictionary objectForKey:versionNumber];

            if (itunesUrl)
            {
                // Show dialog to ask user to update!
            }
            else {
                // Version not in XML
            }
        } @catch (NSException *e) {
            // Error with retrieving the key
        }
    }
    else {
        // Error with parsing data into dictionary
    }
}

しかし、さらなる調査の結果、これはサーバーを使用していない場合に最適なソリューションであることがわかりました。

-(BOOL) needsUpdate{
    NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString* appID = infoDictionary[@"CFBundleIdentifier"];
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://iTunes.Apple.com/lookup?bundleId=%@", appID]];
    NSData* data = [NSData dataWithContentsOfURL:url];
    NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    if ([lookup[@"resultCount"] integerValue] == 1){
        NSString* appStoreVersion = lookup[@"results"][0][@"version"];
        NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
        if (![appStoreVersion isEqualToString:currentVersion]){
            NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
            return YES;
        }
    }
    return NO;
}

の中に:

if (![appStoreVersion isEqualToString:currentVersion]){
                NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
                return YES;
            }

等しくない場合に設定するコードの一部。ここでユーザーをアプリストアに送り、最新バージョンをダウンロードします。

1
C-H-E-F

以下のURLを使用して、AppleアプリのID。

これを取得できますApple itunesconnect.com>アプリ>アプリ情報ページ

GET: http://iTunes.Apple.com/lookup?id=

0
Ruchin Somal