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?

15voto

Danke an Steve Moser für seinen Link, hier ist mein Code:

NSString *appInfoUrl = @"http://itunes.apple.com/en/lookup?bundleId=XXXXXXXXX";

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:appInfoUrl]];
[request setHTTPMethod:@"GET"];

NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection  sendSynchronousRequest:request returningResponse: &response error: &error];
NSString *output = [NSString stringWithCString:[data bytes] length:[data length]];

NSError *e = nil;
NSData *jsonData = [output dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error: &e];

NSString *version = [[[jsonDict objectForKey:@"results"] objectAtIndex:0] objectForKey:@"version"];

1 Stimmen

Sehr gute und korrekte Lösung, nur ein kleines Update bezüglich der Url ist itunes.apple.com/de/lookup?bundleId=xxxxxxxxxx

0 Stimmen

Danke, Ihr Kommentar war zutreffend

5 Stimmen

Tatsächlich funktionierte es bei mir nicht mit dem /en/ Unterpfad. Nachdem ich ihn entfernt hatte, funktionierte es

15voto

emotality Punkte 12295

Verwenden Sie einfach ATAppUpdater . Es ist 1 Zeile, thread-safe und schnell. Es hat auch delegieren Methoden, wenn Sie möchten, um Benutzer-Aktion zu verfolgen.

Hier ist ein Beispiel:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[ATAppUpdater sharedUpdater] showUpdateWithConfirmation]; // 1 line of code
    // or
    [[ATAppUpdater sharedUpdater] showUpdateWithForce]; // 1 line of code

   return YES;
}

Optionale Delegierungsmethoden:

- (void)appUpdaterDidShowUpdateDialog;
- (void)appUpdaterUserDidLaunchAppStore;
- (void)appUpdaterUserDidCancel;

1 Stimmen

Funktioniert das auch für Beta-Versionen in Testflight? Wenn nicht, gibt es ein Tool, das das kann?

0 Stimmen

Nein, es wird nur die aktuelle Version mit der neuesten Version im AppStore verglichen.

0 Stimmen

Können wir das mit Swift verwenden?

14voto

Northern Captain Punkte 1017

Hier ist meine Version mit Mauersegler 4 und beliebt Alamofire Bibliothek (ich verwende sie sowieso in meinen Anwendungen). Die Anfrage ist asynchron und Sie können einen Callback übergeben, um benachrichtigt zu werden, wenn sie fertig ist.

import Alamofire

class VersionCheck {

    public static let shared = VersionCheck()

    var newVersionAvailable: Bool?
    var appStoreVersion: String?

    func checkAppStore(callback: ((_ versionAvailable: Bool?, _ version: String?)->Void)? = nil) {
        let ourBundleId = Bundle.main.infoDictionary!["CFBundleIdentifier"] as! String
        Alamofire.request("https://itunes.apple.com/lookup?bundleId=\(ourBundleId)").responseJSON { response in
            var isNew: Bool?
            var versionStr: String?

            if let json = response.result.value as? NSDictionary,
               let results = json["results"] as? NSArray,
               let entry = results.firstObject as? NSDictionary,
               let appVersion = entry["version"] as? String,
               let ourVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
            {
                isNew = ourVersion != appVersion
                versionStr = appVersion
            }

            self.appStoreVersion = versionStr
            self.newVersionAvailable = isNew
            callback?(isNew, versionStr)
        }
    }
}

Die Verwendung ist einfach:

VersionCheck.shared.checkAppStore() { isNew, version in
        print("IS NEW VERSION AVAILABLE: \(isNew), APP STORE VERSION: \(version)")
    }

1 Stimmen

Das Problem bei der Verwendung von ourVersion != appVersion ist, dass sie ausgelöst wird, wenn das App Store Review Team die neue Version der App überprüft. Wir konvertieren diese Versionsstrings in Zahlen und dann istNeu = appVersion > unsereVersion.

0 Stimmen

@budidino Sie haben recht, ich habe nur den üblichen Ansatz mit Alamofire gezeigt. Wie Sie die Version interpretieren, hängt ganz von Ihrer Anwendung und der Versionsstruktur ab.

0 Stimmen

Nur eine Anmerkung zum Versionsvergleich hinzufügen, ich würde es vorziehen, let serverVersion = "2.7" let localVersion = "2.6.5" let isUpdateAvailable = serverVersion.compare(localVersion, options: .numeric) == .orderedDescending anstatt mit equal zu vergleichen

13voto

Aloha Punkte 71

Swift 5 (Cache-Problem behoben)

enum VersionError: Error {
    case invalidResponse, invalidBundleInfo
}

@discardableResult
func isUpdateAvailable(completion: @escaping (Bool?, Error?) -> Void) throws -> URLSessionDataTask {
    guard let info = Bundle.main.infoDictionary,
        let currentVersion = info["CFBundleShortVersionString"] as? String,
        let identifier = info["CFBundleIdentifier"] as? String,
        let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(identifier)") else {
            throw VersionError.invalidBundleInfo
    }

    let request = URLRequest(url: url, cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData)

    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        do {
            if let error = error { throw error }

            guard let data = data else { throw VersionError.invalidResponse }

            let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any]

            guard let result = (json?["results"] as? [Any])?.first as? [String: Any], let lastVersion = result["version"] as? String else {
                throw VersionError.invalidResponse
            }
            completion(lastVersion > currentVersion, nil)
        } catch {
            completion(nil, error)
        }
    }

    task.resume()
    return task
}

Umsetzung

            try? isUpdateAvailable {[self] (update, error) in
                if let error = error {
                    print(error)
                } else if update ?? false {
                    // show alert
                }
            }

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 .

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