web-dev-qa-db-de.com

Kann ich einen iPhone-Benutzer dazu zwingen, eine Anwendung zu aktualisieren?

Ist es möglich, den Benutzer zur Aktualisierung zu zwingen, sobald eine neue Version meiner Anwendung im iTunes Store verfügbar ist?

Ich arbeite gerade an einer Bewerbung. Ich möchte das Upgrade jedoch jedes Mal erzwingen, wenn ich eine neuere Version hochlade, da das Upgrade mehr Funktionen bietet und ich die vorherige Version verwerfen möchte. Ist dies standardmäßig mit dem iPhone möglich oder muss ich meine eigene Implementierung schreiben, um die aktuelle Version zu überprüfen und mit dem Geschäft zu vergleichen?

43
Nareshkumar

Die einzige Möglichkeit, wie das System mit Updates Ihrer Anwendung umgeht, ist die Aufforderung des Benutzers, dass das Update in der Standardanwendung AppStore verfügbar ist.
Da die Standalone-Anwendung auch keine verfügbaren Updates kennt, müssen Sie Ihren Web-Service implementieren, bei dem die Anwendung prüfen kann, ob die aktuelle Version gültig ist.
Und ich bin nicht sicher, ob dies mit den Apple-Regeln für Anwendungen übereinstimmt, z. B. (es kann kein Korrekturlink gefunden werden), Sie können jedoch keine Testversionen für eine Anwendung hochladen.

* EDIT * Diese Antwort ist nicht mehr wahr. Sehen Sie andere Antworten auf die aktuelle Wahrheit.

4
Vladimir

Ich habe diese Funktion gemacht, indem ich die Version vom iTunes Webservice abgerufen habe und mit der aktuellen Version vergleiche. Nachfolgend mein Code

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

Und fügen Sie die App-ID in den iTunes-Link ein (siehe Code unten).

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

Hinweis: Sie benötigen JSONKit-Frame-Work und ASIHttp-Frame-Work, um die Webservice-Aufrufe durchzuführen.

34
Dilip Rajkumar

Sie können feststellen, ob für die App ein Update erforderlich ist, und anschließend eine benutzerdefinierte Aktion ausführen, beispielsweise den Benutzer benachrichtigen, dass ein Update verfügbar ist. Hier ist ein Codeausschnitt, der feststellt, dass ein Update verfügbar ist. 

-(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;
}
20
datinc

Wenn Sie dies unbedingt tun müssen, können Sie den App Store starten, damit Ihre Benutzer die neueste Version von dort erhalten. Ich würde empfehlen, dies optional zu machen oder zumindest einen Dialog zu präsentieren.

// 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

Diese Frage wurde ursprünglich vor 7 Jahren gepostet, und obwohl einige Antworten relevant bleiben, ist hier ein aktuellerer Ansatz. 

Ich empfehle https://github.com/ArtSabintsev/Siren , das Swift 3-kompatibel ist und mit Cocoapods oder Carthage installiert werden kann.

CocoaPods, Swift 3-Unterstützung:

pod 'Siren'

Karthago:

github "ArtSabintsev/Siren"

9

Ein System für erzwungene Upgrades sollte Teil jeder Anwendung sein, die von etwas außerhalb dieser Anwendung abhängig ist. Sowohl Apple als auch Google behaupten, wenn eine App etwas Externes verwendet, sollte diese externe API für immer leben, sich nie ändern usw. usw., aber das ist einfach unrealistisch. Wenn dies der Fall ist und sich die Dienste, von denen die App abhängig ist, ändern können, kann die App MUSS prüfen, ob sie die Funktionalität und die Eingabeaufforderung einschränken soll Der Benutzer, der die neueste Version oder die neuesten Dinge erhält, wird auf mysteriöse Weise scheitern.

Dies könnte und sollte etwas sein, das Apple und Google bereitstellen, aber sie müssen dies nicht für jede App außerhalb einiger Spiele erstellen, SO ...

Ich habe ein auf Rails basierendes Open-Source-Projekt (Apache 2.0) gestartet, um eine Lösung für dieses Problem zu finden. Es heißt Application- [Ctrl] und ist noch in Arbeit, aber Sie können es gerne verwenden und ich begrüße Beiträge jeglicher Art. Wenn ich dies in meiner Freizeit zum Laufen bringen kann, werde ich dies allen App-Entwicklern mit einem angemessenen Grad an kostenlosem Service zur Verfügung stellen, und natürlich wird jedes Unternehmen immer in der Lage sein, seine eigene Bereitstellung zu starten.

Es ist hier auf GitHub: https://github.com/SlalomDigital/ApplicationCtrl

Trage bei und hilf mir, dieses Problem endgültig zu lösen!

7
Aaron Cooley

Ihr Unternehmens-/Designplan sollte niemals den Ausdruck "Benutzer zwingen" enthalten. Die Leute werden wütend, wenn Sie sie dazu bringen, etwas zu tun. Stellen Sie sich einen Benutzer in Eile vor, der eines Morgens Ihre nette kleine App öffnet, nur um herauszufinden, dass Sie ihn zum Upgrade zwingen, bevor er die App für das, was er braucht, verwenden kann. Stellen Sie sich vor, er ist in der Wildnis und muss Edge zum Herunterladen verwenden. Er wird nicht glücklich sein. 

Wenn Sie diesen Plan lange genug befolgen, führt eines Ihrer Upgrades unweigerlich zu einem merklichen Fehler. Wenn Sie Benutzer dazu zwingen, eine fehlerhafte Version zu verwenden, rebellieren sie. 

Ich wurde von der Erfahrung abhängig gemacht, dass ich mich immer mehr zusammenziehe, wenn "neue Funktionen" zur Beschreibung einer neuen Softwareversion auftreten, da dies unweigerlich das Aufblähen von Funktionen bedeutet. Designer neigen dazu, immer mehr Funktionen in Apps zu integrieren, bis eine App alles tut. Dies ist besonders gefährlich auf einer Plattform wie dem iPhone, auf der eine App schnell genug reagiert, was die Benutzeroberfläche und die Reaktionsfähigkeit der App überfordert. 

Edit01: Mein Kommentar hier So aktualisieren Sie eine Anwendung, nachdem die Benutzer das Upgrade bezahlt haben könnte auch für Ihre Pläne relevant sein. Wenn Ihr Upgrade-Design Apple aus der Einnahmenschleife herausschneidet, ist es kein Starter. 

Update:

Nur zur Klarstellung anhand eines Kommentars unten: Ja, manchmal müssen Benutzer ein Upgrade durchführen. Dies unterscheidet sich jedoch wesentlich von Design der App vom Start, um Benutzer zu zwingen, jedes Mal ein Upgrade durchzuführen, wenn der Entwickler eine neue Version veröffentlicht. 

Ein solches Design soll dem Entwickler das Leben erleichtern und nicht dem Benutzer. Jedes Mal, wenn ein Benutzer ein Upgrade für einen Vorteil durchführen muss, nach dem er nicht gefragt hat und vielleicht nicht möchte, haben Sie dem Kunden Zeit und Ressourcen genommen. Entwürfe, die Zeit und Aufwand vom Entwickler zum Anwender abwälzen, sind schlechte Entwürfe, weil die Leute letztendlich Software zu ihrem eigenen Vorteil kaufen. Wenn Sie diesen Vorteil verringern, verringern Sie die Rentabilität der Software. 

Daher sollte kein Designer eine Software entwickeln, die die Benutzer dazu zwingt, etwas zu tun, das der Benutzer nicht wünscht, es sei denn, dies ist eine absolute technische Notwendigkeit. Dies ist natürlich eine Faustregel, aber es ist eine sehr gute. 

4
TechZen

Mein App-Update für den App Store wurde genau aus diesem Grund abgelehnt. Wir haben eine Funktion hinzugefügt, um die installierte Version mit der aktuellen Version zu vergleichen. Wenn es sich nicht um eine unterstützte Version handelt, wird die Aktualisierung dieser Versionen erzwungen. 

Apple hat dies abgelehnt.

Also zurück zum Design Board!

4
Steig

Die anderen Antworten deuten darauf hin, dass man die erzwungene Aktualisierungsfunktion selbst implementieren muss. Es ist wirklich eine Schande, ich wünschte, es wäre nicht so .. Meine erste Aktualisierung einer iOS-Anwendung soll morgen veröffentlicht werden und zum Glück Es ist kein Problem, da wir nur Änderungen an der App vorgenommen haben. Wenn wir jedoch die Struktur unserer Webservices ändern, wäre es wirklich nützlich, Updates zu erzwingen. Damit unser Server nicht jede App-Version unterstützen muss.

Es gibt jedoch eine Alternative zu erzwungenen Aktualisierungen, die in diesem Thread nicht erwähnt zu werden scheint. Sie könnten jeden Webservice-Aufruf haben, der Daten erzeugt, ein Schema an die Daten anhängen,., Das der App mitteilt, wie diese Daten deserialisiert werden sollen Dies ermöglicht Ihnen, die Struktur der durch get-request erzeugten Daten zu ändern, ohne die Deserialisierung in der App zu unterbrechen. Dies setzt natürlich voraus, dass der Interpreter, den Sie schreiben, sich selbst nicht ändert, was aber der Fall ist eine etwas vernünftige Annahme, wenn sie ausgereift ist.

Post-Requests könnten durch Interaktion "schema-fied" werden . Damit meine ich, dass Sie vor jeder Post-Request-Anweisung nach Anweisungen zum Aufrufen des aktuellen Webservice ..__ fragen. Sie verarbeiten die Anweisungen mit ein angehängtes Schema dafür, und dann machen Sie den eigentlichen Aufruf des Webservice . Dies bedeutet im Wesentlichen, dass für jede Post-Anforderung 2 Anforderungen erforderlich sind. Dies kann jedoch in Ordnung sein.

Unabhängig davon, ob Sie eine erzwungene Aktualisierung oder eine Schemainterpretation implementieren, muss die Funktionalität ab dem ersten Tag in der App vorhanden sein, wenn sie im App Store auftaucht .. __ Ansonsten befinden Sie sich im gleichen Chaos. All diese Komplexität wäre unnötig, wenn Apple eine erzwungene Aktualisierung für uns Entwickler implementiert hat. Die Interpretation des Schemas wäre dennoch eine Verbesserung der Verwendbarkeit, wenn die erzwungene Aktualisierung vorhanden wäre. Aber es beunruhigt mich ein wenig, dass Apple keine Aktualisierung erzwungen hat , weil man damit zumindest nach Veröffentlichung der App eigene Anti-Break-Update-Maßnahmen einführen könnte.

3

Es gibt keine automatisierte Methode, Sie müssten etwas manuell schreiben.

3
kubi

Hallo für alle in der Zukunft habe ich dieses Tutorial gefunden, das jedem helfen sollte, es hat mir geholfen. 

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

Bearbeiten (Ihr Code sieht ungefähr so ​​aus, wie unten beschrieben):

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

Nach weiteren Untersuchungen habe ich jedoch festgestellt, dass dies eine großartige Lösung ist, wenn Sie keinen Server verwenden. 

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

In dem:

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

Teil des Codes, den Sie festlegen, was Sie tun möchten, wenn er nicht gleich ist. Hier senden Sie den Benutzer an den App Store, um die neueste Version herunterzuladen.

1
C-H-E-F

Unter URL können Sie die Informationen zu jeder App abrufen. Sie kennen nur Ihre Apple-ID Ihrer App.

Sie erhalten diese Apple ID auf der Seite itunesconnect.com> Ihrer App> App-Informationen

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

0
Ruchin Somal