iOS not getting accurate App version from iTunes

Viewed 1118

Actually Just want to implement functionality like if new version of the app is available on AppStore then end user will be notified for update the App.

There are so many answers on google but look at below my code.

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/in/lookup?bundleId=\(identifier)") else {
                throw VersionError.invalidBundleInfo
        }
        print(currentVersion)
        let task = URLSession.shared.dataTask(with: url) { (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]
                 if let a = ((json?["results"] as? [Any])?.first) as? [String: Any] {
                print(a["version"] as? String ?? "")
            }
                guard let result = (json?["results"] as? [Any])?.first as? [String: Any], let version = result["version"] as? String else {
                    throw VersionError.invalidResponse
                }
                completion(version != currentVersion, nil)
            } catch {
                completion(nil, error)
            }
        }
        task.resume()
        return task
    }

and calling this function

 _ = try? appDelegate.isUpdateAvailable { (update, error) in
            if let error = error {
                print(error)
            } else if let update = update {
                if update {
                    let alert = UIAlertController(title: "New Version Available", message: "New version of application is available please update now!", preferredStyle: UIAlertControllerStyle.alert)
                    alert.addAction(UIAlertAction(title: "Update", style: .default, handler: { (actionOk) in

                        if let url = URL(string: "itms-apps://itunes.apple.com/app/idXXXXXXXXX"),
                            UIApplication.shared.canOpenURL(url){
                            UIApplication.shared.open(url, options: [:])
                        }
                    }))
                    self.present(alert, animated: true, completion: nil)
                }
            }
        }

Problem is that If new version of app is ready to sell and I open old version of app then popup will open and when I click on update button, It will redirect on AppStore. But on AppStore rather then display "Update" button, it display "Open" button

So I checked in my code.

When I run below URL manually on browser

http://itunes.apple.com/in/lookup?bundleId=com.mycompany.appname

Then download .txt file and got accurate App version But In my code print(a["version"] as? String ?? "") it returns wrong version number.

Where I'm going wrong? Please correct me.

NOTE: I also used http://itunes.apple.com/lookup?bundleId=com.mycompany.appname means removed country code from URL but not worked for me.

3 Answers

Your code looks correct. As Coeur said, Apple puts out the new update gradually and it won't be immediate. The update is usually finished after 24 hours.

Personally, I won't go with this approach. It's better to fetch the version from your server and you can update that value after 24 hours when the App is released. You'll have more control over it. Supposedly your new app is buggy. You have a choice of not prompting your user to update to that version.

Side tip:

  • Make sure you only show the popup once.
  • Don't show the popup if server version is lower. Another freedom to support "not" prompting the user to update.

This is headache issue for all iOS Developer to detect version of the App and notify to users for new update. BTW @Cœur and @Alexis O explained well so I don't think to explain more. Just follow my code.

By calling below URL you will be got .txt file

http://itunes.apple.com/in/lookup?bundleId=com.mycompany.appname

In the file you also will find currentVersionReleaseDate, Use this data and time and compare with current date and time if it is grater then 24 hours? then you should display popup for update the App.

Changed your code:

if let a = ((json?["results"] as? [Any])?.first) as? [String: Any] {
                    print(a["version"] as? String ?? "")
                    let currentVersionDate = a["currentVersionReleaseDate"] as? String ?? ""
                    let dateFormatter = DateFormatter()
                    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
                    dateFormatter.locale = Locale(identifier: "en_US_POSIX")

                    if let myDate = dateFormatter.date(from: currentVersionDate) {
                        let diff = Calendar.current.dateComponents([.hour], from: myDate, to: Date()).hour ?? 0
                        if diff < 24 {
                            completion(false, nil)
                            return
                        }
                    }
                }

Changed in If statement . Check it.

You can try this:

   func isAppUpdateAvailable() throws -> Bool {
        let yourAppleID = "12454364536" //This is demo id, you can get your apple id for a specific app from the appinformation tab of itunesconnect account 
        guard let info = Bundle.main.infoDictionary,
            let currentVersion = info["CFBundleShortVersionString"] as? String,
            let url = URL(string: "http://itunes.apple.com/lookup?id=\(yourAppleID)") else {
                throw VersionError.invalidBundleInfo
        }
        let data = try Data(contentsOf: url)
        guard let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any] else {
            throw VersionError.invalidResponse
        }
        if let result = (json["results"] as? [Any])?.first as? [String: Any], let version = result["version"] as? String {
            print("version in app store", version,currentVersion);

            return version != currentVersion
        }
        throw VersionError.invalidResponse
    }

This is check for sending it on appstore: //This is you appstore URL of respective app, you can direct put your appstore URL here

 let appStoreURl = "https://itunes.apple.com/sg/app/AppName/idXXXXXXXXXX?ls=1&mt=8"
 if let url = URL(string: appStoreURl),
                                UIApplication.shared.canOpenURL(url){
    UIApplication.shared.open(url, options: [:])
 }
Related