174 Stimmen

Prüfen, ob meine App eine neue Version im AppStore hat

Ich möchte manuell prüfen, ob es neue Updates für meine App gibt, während der Benutzer sich in ihr befindet, und ihn auffordern, die neue Version herunterzuladen. Kann ich dies tun, indem ich die Version meiner App im App Store - programmatisch - überprüfe?

8voto

Andrea Punkte 588

Ich kann diese kleine Bibliothek empfehlen: https://github.com/nicklockwood/iVersion

Ihr Zweck ist es, die Handhabung von entfernten Listen zu vereinfachen, um Benachrichtigungen auszulösen.

3 Stimmen

Sie können im App Store direkt nach der Versionsnummer suchen, anstatt irgendwo eine plist-Datei zu hosten. Sehen Sie sich diese Antwort an: stackoverflow.com/a/6569307/142358

1 Stimmen

IVersion verwendet nun automatisch die Version aus dem App Store - die Plist ist optional, wenn Sie andere Versionshinweise als die in iTunes angeben wollen, aber Sie müssen sie nicht verwenden.

1 Stimmen

Dieser Code könnte einige Verbesserungen vertragen, ist aber viel besser als die anderen Antworten, die eine synchrone Anfrage senden. Trotzdem ist die Art und Weise, wie es Threading tut, schlechter Stil. Ich werde Probleme auf Github einreichen.

8voto

Kassem Itani Punkte 959

Swift 3.1

func needsUpdate() -> Bool {
    let infoDictionary = Bundle.main.infoDictionary
    let appID = infoDictionary!["CFBundleIdentifier"] as! String
    let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(appID)")
    guard let data = try? Data(contentsOf: url) else {
      print("There is an error!")
      return false;
    }
    let lookup = (try? JSONSerialization.jsonObject(with: data! , options: [])) as? [String: Any]
    if let resultCount = lookup!["resultCount"] as? Int, resultCount == 1 {
        if let results = lookup!["results"] as? [[String:Any]] {
            if let appStoreVersion = results[0]["version"] as? String{
                let currentVersion = infoDictionary!["CFBundleShortVersionString"] as? String
                if !(appStoreVersion == currentVersion) {
                    print("Need to update [\(appStoreVersion) != \(currentVersion)]")
                    return true
                }
            }
        }
    }
    return false
}

0 Stimmen

Dies führt zum Absturz, wenn Sie keine Internetverbindung haben. let data = try? Data(contentsOf: url!) wird null zurückgeben, und in der nächsten Zeile machen Sie data!

0 Stimmen

Thx @JorisMans Ich werde es für keine Internetverbindung Absturz aktualisieren

1 Stimmen

Tun Sie das nicht. Verwenden Sie URLSession .

7voto

Nitesh Borad Punkte 4502

Diese Antwort ist eine Änderung der Antwort von datinc https://stackoverflow.com/a/25210143/2735358 .

Die Funktion von datinc vergleicht die Version durch einen Stringvergleich. Sie vergleicht die Version also nicht auf "größer als" oder "kleiner als".

Aber diese geänderte Funktion vergleicht Version durch NSNumericSearch (numerischer Vergleich) .

- (void)checkForUpdateWithHandler:(void(^)(BOOL isUpdateAvailable))updateHandler {

    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appID = infoDictionary[@"CFBundleIdentifier"];
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/lookup?bundleId=%@", appID]];
    NSLog(@"iTunes Lookup URL for the app: %@", url.absoluteString);

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *theTask = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url]
                                               completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

                                                   NSDictionary *lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                                                   NSLog(@"iTunes Lookup Data: %@", lookup);
                                                   if (lookup && [lookup[@"resultCount"] integerValue] == 1){
                                                       NSString *appStoreVersion = lookup[@"results"][0][@"version"];
                                                       NSString *currentVersion = infoDictionary[@"CFBundleShortVersionString"];

                                                       BOOL isUpdateAvailable = [appStoreVersion compare:currentVersion options:NSNumericSearch] == NSOrderedDescending;
                                                       if (isUpdateAvailable) {
                                                           NSLog(@"\n\nNeed to update. Appstore version %@ is greater than %@",appStoreVersion, currentVersion);
                                                       }
                                                       if (updateHandler) {
                                                           updateHandler(isUpdateAvailable);
                                                       }
                                                   }
                                               }];
    [theTask resume];
}

Verwendung:

[self checkForUpdateWithHandler:^(BOOL isUpdateAvailable) {
    if (isUpdateAvailable) {
        // show alert
    }
}];

3 Stimmen

Diese Antwort stellt ihre Anfrage synchron. Das bedeutet, dass Ihre Anwendung bei einer schlechten Verbindung minutenlang unbrauchbar sein kann, bis die Anfrage zurückkommt.

0 Stimmen

NSURLSession arbeitet automatisch in Hintergrund-Threads, sofern nicht anders angegeben.

6voto

tyler_mitchell Punkte 1697

Aus einer Hybrid-Anwendung POV, dies ist ein Javascript-Beispiel, ich habe ein Update verfügbar Fußzeile auf meinem Hauptmenü. Wenn ein Update verfügbar ist (d.h. meine Versionsnummer in der Konfigurationsdatei ist kleiner als die Version abgerufen, die Fußzeile anzeigen) Dies wird dann den Benutzer auf den App-Store, wo der Benutzer dann die Update-Schaltfläche klicken können.

Ich erhalte auch die neuen Daten (z.B. Release Notes) und zeige diese in einem Modal beim Login an, wenn es das erste Mal mit dieser Version ist.

Die Methode Update Available kann beliebig oft ausgeführt werden. Meine wird jedes Mal ausgeführt, wenn der Benutzer zum Startbildschirm navigiert.

function isUpdateAvailable() {
        $.ajax('https://itunes.apple.com/lookup?bundleId=BUNDLEID', {
            type: "GET",
            cache: false,
            dataType: 'json'
        }).done(function (data) {
            _isUpdateAvailable(data.results[0]);
        }).fail(function (jqXHR, textStatus, errorThrown) {
            commsErrorHandler(jqXHR, textStatus, false);
        });

}

Rückruf: Apple hat eine API, also sehr einfach zu bekommen

function isUpdateAvailable_iOS (data) {
    var storeVersion = data.version;
    var releaseNotes = data.releaseNotes;
    // Check store Version Against My App Version ('1.14.3' -> 1143)
    var _storeV = parseInt(storeVersion.replace(/\./g, ''));
    var _appV = parseInt(appVersion.substring(1).replace(/\./g, ''));
    $('#ft-main-menu-btn').off();
    if (_storeV > _appV) {
        // Update Available
        $('#ft-main-menu-btn').text('Update Available');
        $('#ft-main-menu-btn').click(function () {
           // Open Store      
           window.open('https://itunes.apple.com/us/app/appname/idUniqueID', '_system');
        });

    } else {
        $('#ft-main-menu-btn').html(' ');
        // Release Notes
        settings.updateReleaseNotes('v' + storeVersion, releaseNotes);
    }
}

6voto

CodeChanger Punkte 7433

Versuchen Sie dies mit einem einzigen Funktionsaufruf:

func showAppStoreVersionUpdateAlert(isForceUpdate: Bool) {

    do {
        //Get Bundle Identifire from Info.plist
        guard let bundleIdentifire = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String else {
            print("No Bundle Info found.")
            throw CustomError.invalidIdentifires
        }

        // Build App Store URL
        guard let url = URL(string:"http://itunes.apple.com/lookup?bundleId=" + bundleIdentifire) else {
            print("Isse with generating URL.")
            throw CustomError.invalidURL
        }

        let serviceTask = URLSession.shared.dataTask(with: url) { (responseData, response, error) in

            do {
                // Check error
                if let error = error { throw error }
                //Parse response
                guard let data = responseData else { throw CustomError.jsonReading }
                let result = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
                let itunes = ItunesAppInfoItunes.init(fromDictionary: result as! [String : Any])
                print(itunes.results)
                if let itunesResult = itunes.results.first {
                    print("App Store Varsion: ",itunesResult.version)

                    //Get Bundle Version from Info.plist
                    guard let appShortVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
                        print("No Short Version Info found.")
                        throw CustomError.invalidVersion
                    }

                    if appShortVersion == itunesResult.version {
                        //App Store & Local App Have same Version.
                        print("Same Version at both side")
                    } else {
                        //Show Update alert
                        var message = ""
                        //Get Bundle Version from Info.plist
                        if let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String {
                            message = "\(appName) has new version(\(itunesResult.version!)) available on App Store."
                        } else {
                            message = "This app has new version(\(itunesResult.version!)) available on App Store."
                        }

                        //Show Alert on the main thread
                        DispatchQueue.main.async {
                            self.showUpdateAlert(message: message, appStoreURL: itunesResult.trackViewUrl, isForceUpdate: isForceUpdate)
                        }
                    }
                }
            } catch {
                print(error)
            }
        }
        serviceTask.resume()
    } catch {
        print(error)
    }
}

Alert-Funktion zum Öffnen der AppStore-URL:

func showUpdateAlert(message : String, appStoreURL: String, isForceUpdate: Bool) {

    let controller = UIAlertController(title: "New Version", message: message, preferredStyle: .alert)

    //Optional Button
    if !isForceUpdate {
        controller.addAction(UIAlertAction(title: "Later", style: .cancel, handler: { (_) in }))
    }

    controller.addAction(UIAlertAction(title: "Update", style: .default, handler: { (_) in
        guard let url = URL(string: appStoreURL) else {
            return
        }
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(url)
        }

    }))

    let applicationDelegate = UIApplication.shared.delegate as? AppDelegate
    applicationDelegate?.window?.rootViewController?.present(controller, animated: true)

}

So rufen Sie die obige Funktion auf:

AppStoreUpdate.shared.showAppStoreVersionUpdateAlert(isForceUpdate: false/true)

Weitere Einzelheiten finden Sie unter dem folgenden Link mit dem vollständigen Code:

AppStoreUpdate.swift

ItunesAppInfoResult.swift

ItunesAppInfoItunes.swift

Ich hoffe, das hilft!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X