检查我的IOS应用程序是否已更新

时间:2013-06-03 14:46:31

标签: ios objective-c swift uiapplication

我需要检查我的应用程序何时启动,如果它正在更新,因为我需要 创建仅在首次安装应用程序后才会显示的视图 更新。

8 个答案:

答案 0 :(得分:38)

您可以将值(例如当前应用版本号)保存到NSUserDefaults,并在每次用户启动应用时进行检查。

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

版本如下所示:

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

版本如下所示:

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

答案 1 :(得分:6)

您可以在NSUserDefaults中存储应用版本号,并在每次启动应用时进行检查。如果号码不可用,则为全新安装。如果它被更改,则是升级。

答案 2 :(得分:3)

版本与已接受的答案相比有了重大改进:

  • 使用infoDictionary代替objectForInfoDictionaryKey保证结果与设备语言无关,否则您可能会在极少数情况下认为存在升级,而实际上它只是一种设备语言改变
  • 使用与主Bundle infoDictionary相同的UserDefaults密钥,以明确存储的内容
  • 分解设置currentVersion代码
  • Swift 3语法

代码:

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

答案 3 :(得分:2)

Swift 3.x

在应用启动时初始化AppVersionUpdateNotifier并遵循AppUpdateNotifier协议,享受。

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

        } 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
    }
}
//*************************
//Use: Example
//*************************

extention AppDelagate: AppUpdateNotifier {
    func onVersionUpdate(newVersion: Int, oldVersion: Int) {
        // do something
    }

    func onFirstLaunch() {
        //do something
    }
}

答案 4 :(得分:0)

这是一个简单的代码,可以知道当前版本是否不同(此代码也适用于模拟器。)

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

注意:确保在iTunes中输入新版本时,这与您要发布的应用中的版本相匹配。如果没有,则无论用户是否更新,上述代码将始终返回YES。

答案 5 :(得分:0)

我认为,当您使用小型应用程序时,给出的答案是很好的,但是当您使用路线图较长的大型iOS应用程序时,您肯定需要一个功能强大且具有未来感的解决方案,其好处是。

  1. 更好的比较逻辑,可以在所有可能性(2.0 / 2.0.0等)下正常工作。
  2. 在迁移过程中采取特定措施,假设在用户迁移时 从版本1.0到2.0,从版本1.1到2.0。
  3. 当用户重置应用程序(注销)时,重置缓存版本。

下面是我在一个iOS应用中使用的代码段。

public enum VersionConfigResponse {
    case freshInstalled
    case versionGreater
    case versionEqualOrLesser
    case currentVersionEmpty
}


/*
 Config manager responsible to handle the change needs to be done when user migrate from one Version to another Version.
 */
public class VersionConfig {

    public static let shared = VersionConfig()
    private init() { }
    private let versionKey = "SAVED_SHORT_VERSION_STRING"

    /*
     Cache the existing version for compare during next app launch.
     */
    private var storedVersion : String?  {
        get {
            return UserDefaults.standard.object(forKey: versionKey) as? String
        } set {
            UserDefaults.standard.set(newValue, forKey: versionKey)
            UserDefaults.standard.synchronize()
        }
    }

    /*
     Validate the current version with saved version, if greater do clean.
     */
    public func validate(currentVersion: String?) -> VersionConfigResponse  {
        guard let currentVersion = currentVersion else {
            return .currentVersionEmpty
        }

        guard let sVersion = storedVersion else {
            self.storedVersion = currentVersion
            self.freshInstalled()
            return .freshInstalled
        }

        if currentVersion.compare(sVersion, options: .numeric, range: nil, locale: nil) == .orderedDescending    {
            self.storedVersion = currentVersion
            self.userMigrated(fromVersion: sVersion, toVersion:currentVersion)
            return .versionGreater
        } else {
            return .versionEqualOrLesser
        }
    }

    private func userMigrated(fromVersion: String, toVersion: String)   {
        //take your action here...
    }

    private func freshInstalled()   {
        //take your action here...
    }

    /*
     Remove saved version if user reset(logout) the app.
     */
    public func reset() {
        self.storedVersion = nil
    }
}


//trigger version config with current version
VersionConfig.shared.validate(currentVersion: "1.0.0")

//reset when user logsout
VersionConfig.shared.reset()

答案 6 :(得分:0)

我创建了BundleInfoVersioning快速包来帮助我解决此问题。

它适用于信息词典中的所有键,例如CFBundleVersionCFBundleShortVersionString,以及自定义键路径,例如NSAgora/DatabaseVersion

示例:

let bundleInfoVersioning = BundleInfoVersioning(bundle: .main)

bundleInfoVersioning.check(forKeyPath: "CFBundleVersion") { (old: String?, new: String?) in
    if old == nil {
        Analytics.install(version: new)
    }
    else {
        Analytics.update(from: old, to: new)
    }
}

bundleInfoVersioning.check(forKeyPath: "CFBundleShortVersionString") { _ , newVersion in
    self.showWhatsNew(in: newVersion)
}

bundleInfoVersioning.check(forKeyPath: "NSAgora/DatabaseVersion") { (old: Int?, new: Int?) in
    self.resetDataBase()
}

您可以在github上的https://github.com/nsagora/bundle-info-versioning上进行检查。

答案 7 :(得分:0)

这对我有用。

func compareVersion(old:String,latest:String) -> Bool {
 if latest.compare(old, options: .numeric) == .orderedDescending {
     return true
 }
   return false
 }

compareVersion(old: "3.1.5", latest: "3.2")