App Version Check
AppStore Updates
Mobile App Management
Software Updates
Version Tracking

Check if my app has a new version on AppStore

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want an iOS app to know whether a newer App Store version exists, the usual approach is to query Apple’s lookup endpoint, read the latest version string for your bundle identifier, and compare it with the version bundled in the app. The implementation is straightforward, but the comparison logic and user experience deserve more care than the network request itself.

Query the App Store Lookup Endpoint

Apple’s lookup API can return metadata for an app by bundle identifier. A typical request looks like this:

text
https://itunes.apple.com/lookup?bundleId=com.example.myapp

You can call that from Swift and decode the result:

swift
1import Foundation
2
3struct LookupResponse: Decodable {
4    let resultCount: Int
5    let results: [AppStoreApp]
6}
7
8struct AppStoreApp: Decodable {
9    let version: String
10    let trackViewUrl: String
11}
12
13func fetchAppStoreVersion(
14    bundleID: String,
15    completion: @escaping (Result<AppStoreApp, Error>) -> Void
16) {
17    let url = URL(string: "https://itunes.apple.com/lookup?bundleId=\(bundleID)")!
18
19    URLSession.shared.dataTask(with: url) { data, _, error in
20        if let error = error {
21            completion(.failure(error))
22            return
23        }
24
25        guard let data = data else {
26            completion(.failure(NSError(domain: "VersionCheck", code: 1)))
27            return
28        }
29
30        do {
31            let decoded = try JSONDecoder().decode(LookupResponse.self, from: data)
32            guard let app = decoded.results.first else {
33                completion(.failure(NSError(domain: "VersionCheck", code: 2)))
34                return
35            }
36            completion(.success(app))
37        } catch {
38            completion(.failure(error))
39        }
40    }.resume()
41}

That gives you the store version and the App Store URL you can send the user to if an update is available.

Compare Versions Carefully

Do not compare version strings lexicographically. For example, "1.10" is newer than "1.9", but plain string comparison can get that wrong.

This helper compares dotted numeric versions:

swift
1func isStoreVersionNewer(local: String, store: String) -> Bool {
2    let localParts = local.split(separator: ".").compactMap { Int($0) }
3    let storeParts = store.split(separator: ".").compactMap { Int($0) }
4    let count = max(localParts.count, storeParts.count)
5
6    for index in 0..<count {
7        let localValue = index < localParts.count ? localParts[index] : 0
8        let storeValue = index < storeParts.count ? storeParts[index] : 0
9
10        if storeValue > localValue { return true }
11        if storeValue < localValue { return false }
12    }
13
14    return false
15}

And here is how you tie it together:

swift
1let localVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0"
2let bundleID = Bundle.main.bundleIdentifier ?? ""
3
4fetchAppStoreVersion(bundleID: bundleID) { result in
5    switch result {
6    case .success(let app):
7        if isStoreVersionNewer(local: localVersion, store: app.version) {
8            print("Update available at \(app.trackViewUrl)")
9        } else {
10            print("Already up to date")
11        }
12    case .failure(let error):
13        print("Version check failed: \(error)")
14    }
15}

Decide How Aggressive the Prompt Should Be

Technically, checking the version is easy. Product behavior is the harder decision.

A reasonable strategy is:

  • check occasionally, not on every foreground event
  • prompt softly for optional updates
  • reserve blocking prompts for critical compatibility or security updates

You should also expect App Store data to lag briefly after a release. If a fresh version just went live, the lookup response may not reflect it immediately in every region.

Regional and Packaging Details

If your app is not available in every storefront, the result can depend on the country context. Apple’s lookup API supports a country parameter when you need to be explicit.

Also decide which bundle value you compare:

  • 'CFBundleShortVersionString for marketing version'
  • 'CFBundleVersion for build number'

Most user-facing update checks compare the marketing version, because that is what appears in the App Store listing.

Common Pitfalls

The biggest mistake is comparing versions as plain strings. Numeric version components should be compared piece by piece.

Another issue is assuming the network result is always present. The app may be offline, the lookup may fail, or the bundle identifier may not return a result in the expected storefront.

Developers also sometimes prompt too often. Even a correct update checker becomes annoying if it interrupts users repeatedly for minor releases.

Finally, do not use the update checker as a security boundary. It is a user-experience feature, not a reliable enforcement mechanism.

Summary

  • Query Apple’s lookup endpoint by bundle identifier to get the latest App Store version.
  • Compare version numbers numerically, not as raw strings.
  • Use CFBundleShortVersionString for typical user-facing checks.
  • Prompt users thoughtfully instead of showing an alert on every launch.
  • Expect occasional API lag and network failure cases.

Course illustration
Course illustration

All Rights Reserved.