Check if my IOS application is updated

21,447

Solution 1

You could save a value (e.g. the current app version number) to NSUserDefaults and check it every time the user starts the app.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *currentAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    NSString *previousVersion = [defaults objectForKey:@"appVersion"];
    if (!previousVersion) {
        // first launch

        // ...

        [defaults setObject:currentAppVersion forKey:@"appVersion"];
        [defaults synchronize];
    } else if ([previousVersion isEqualToString:currentAppVersion]) {
        // same version
    } else {
        // other version

        // ...

        [defaults setObject:currentAppVersion forKey:@"appVersion"];
        [defaults synchronize];
    }



    return YES;
}

The version looks like this:

let defaults = NSUserDefaults.standardUserDefaults()

let currentAppVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
let previousVersion = defaults.stringForKey("appVersion")
if previousVersion == nil {
    // first launch
    defaults.setObject(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
} else if previousVersion == currentAppVersion {
    // same version
} else {
    // other version
    defaults.setObject(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
}

The version looks like this:

let defaults = UserDefaults.standard

let currentAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let previousVersion = defaults.string(forKey: "appVersion")
if previousVersion == nil {
    // first launch
    defaults.set(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
} else if previousVersion == currentAppVersion {
    // same version
} else {
    // other version
    defaults.set(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
}

Solution 2

you can store a app version number in NSUserDefaults and check it every time your app is launched. If the number is not available, its a fresh installation. If it is changed , it is an upgrade.

Solution 3

Just initialise AppVersionUpdateNotifier in app launch and conform AppUpdateNotifier protocol, enjoy.

Use: Swift 3.x

extension AppDelegate: AppUpdateNotifier {
    func onVersionUpdate(newVersion: Int, oldVersion: Int) {
        // do something
    }
    
    func onFirstLaunch() {
        //do something
    }
}
    class AppVersionUpdateNotifier {
        static let KEY_APP_VERSION = "key_app_version"
        static let shared = AppVersionUpdateNotifier()
        
        private let userDefault:UserDefaults
        private var delegate:AppUpdateNotifier?
        
        private init() {
            self.userDefault = UserDefaults.standard
        }
        
        func initNotifier(_ delegate:AppUpdateNotifier) {
            self.delegate = delegate
            checkVersionAndNotify()
        }
        
        private func checkVersionAndNotify() {
            let versionOfLastRun = userDefault.object(forKey: AppVersionUpdateNotifier.KEY_APP_VERSION) as? Int
            let currentVersion = Int(Bundle.main.buildVersion)!
            
            if versionOfLastRun == nil {
                // First start after installing the app
                delegate?.onFirstLaunch()
            } else if versionOfLastRun != currentVersion {
                // App was updated since last run
                delegate?.onVersionUpdate(newVersion: currentVersion, oldVersion: versionOfLastRun!)
            } else {
                // nothing changed
                
            }
            userDefault.set(currentVersion, forKey: AppVersionUpdateNotifier.KEY_APP_VERSION)
        }
    }
    
    protocol AppUpdateNotifier {
        func onFirstLaunch()
        func onVersionUpdate(newVersion:Int, oldVersion:Int)
    }
    extension Bundle {
        var shortVersion: String {
            return infoDictionary!["CFBundleShortVersionString"] as! String
        }
        var buildVersion: String {
            return infoDictionary!["CFBundleVersion"] as! String
        }
    }

Solution 4

version with an important improvement over the accepted answer:

  • using infoDictionary instead of objectForInfoDictionaryKey guaranties that the result is independent from device language, otherwise you may end up in some rare cases believing that there is an upgrade when in reality it is just a device language change
  • using a UserDefaults key identical to the main Bundle infoDictionary for clarity on what is exactly stored
  • factoring setting currentVersion code
  • Swift 3 syntax

Code:

    let standardUserDefaults = UserDefaults.standard
    let shortVersionKey = "CFBundleShortVersionString"
    let currentVersion = Bundle.main.infoDictionary![shortVersionKey] as! String
    let previousVersion = standardUserDefaults.object(forKey: shortVersionKey) as? String
    if previousVersion == currentVersion {
        // same version
    } else {
        // replace with `if let previousVersion = previousVersion {` if you need the exact value
        if previousVersion != nil {
            // new version
        } else {
            // first launch
        }
        standardUserDefaults.set(currentVersion, forKey: shortVersionKey)
        standardUserDefaults.synchronize()
    }

Solution 5

Here is a simple code to know if the current version is different (this code work on simulator too.)

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

Note: Make sure that when you enter the new version in iTunes, this matches the version in the app you are releasing. If not then the above code will always return YES regardless if the user updates.

Share:
21,447

Related videos on Youtube

user2412870
Author by

user2412870

Updated on July 09, 2022

Comments

  • user2412870
    user2412870 almost 2 years

    I need to check when my app launches if it was being updated, because i need to make a view that only appears when the app is firstly installed to appear again after being updated.

    • Michael Dautermann
      Michael Dautermann about 11 years
      you need to elaborate on this question: what is being updated? the app itself or files within the app or files to be downloaded from a remote server?
    • user2412870
      user2412870 about 11 years
      the app itself is being updated
  • user2412870
    user2412870 about 11 years
    I read that after an update the NSUserDefaults doesn't get deleted, so that wouldn't not help me, that would work if a user deletes the application first and the reinstall it
  • pre
    pre about 11 years
    @user2412870 Store your version number in NSUserDefaults and check, if updated you can check if the version number is similar to the number saved in NSUserDefaults
  • damithH
    damithH over 10 years
    how we check if already shipped app not supporting the above mechanism ?
  • Cœur
    Cœur about 7 years
    @damithH if your shipped app was using NSUserDefaults, then simply check for the existence of whatever key you were using.
  • Alok Chandra
    Alok Chandra about 5 years
    great...Thanks.
  • Viennarz Valdevieso Curtiz
    Viennarz Valdevieso Curtiz over 4 years
    Apple docs says synchronize() Waits for any pending asynchronous updates to the defaults database and returns; this method is unnecessary and shouldn't be used. Synchronize
  • Vishal Sonawane
    Vishal Sonawane almost 4 years
    Do not simply copy-paste the solutions from other's answers [stackoverflow.com/a/25210143/4387347]. Try to add your own suggestions/improvements.