如何检测iOS应用程序是否已安装或升级?

27

我正在开发一款应用程序,需要知道用户是首次安装还是从App Store升级的。

如何检测应用程序是首次安装,还是升级或重新安装?

非常感谢您提前的答复。

5个回答

39

通过将最新已知版本保存到standardUserDefaults,您可以轻松区分安装应用程序后的第一次启动、更新后的第一次启动和其他启动。但据我所知,不可能检测到应用程序的重新安装,因为当应用程序从设备中删除时,所有与应用程序相关的数据也会被删除。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSString* currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
    NSString* versionOfLastRun = [[NSUserDefaults standardUserDefaults] objectForKey:@"VersionOfLastRun"];

    if (versionOfLastRun == nil) {
        // First start after installing the app
    } else if (![versionOfLastRun isEqual:currentVersion]) {
        // App was updated since last run
    } else {
        // nothing changed 
    }

    [[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:@"VersionOfLastRun"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

也许将版本号存储到钥匙串中会起作用?我认为钥匙串中的数据在应用被卸载后并不会被删除。 - Sweeper
你什么时候更新之前的版本? - Gerald
@Nero 我更改 Build number 时可以工作,但更改版本号不能。有任何想法吗? - Sethmr
1
@Sethmr 哦,没错。感谢你指出这个问题。CFBundleVersion实际上返回的是Xcode称之为构建号的内容,但还有另一个键CFBundleShortVersionString,它返回你在项目编辑器中输入的版本号。 - Nero
需要实际记录版本/构建号的标准化格式,而不是允许完全自由地使用!只有在看到这两个变量之后,我才意识到构建基本上是版本的扩展。我之前将其视为没有“。”来标识哪个版本的Int。 - Sethmr
请勿使用objectForInfoDictionaryKey来比较版本号!请参阅https://dev59.com/yWQn5IYBdhLWcg3wW2D3#42552076 - Cœur

20

查看Swift 3.0版本的代码。
注意:使用CFBundleShortVersionString来检查实际应用程序的版本。

func checkAppUpgrade() {
    let currentVersion = Bundle.main.object(forInfoDictionaryKey:     "CFBundleShortVersionString") as? String
    let versionOfLastRun = UserDefaults.standard.object(forKey: "VersionOfLastRun") as? String

    if versionOfLastRun == nil {
        // First start after installing the app

    } else if versionOfLastRun != currentVersion {
        // App was updated since last run

    } else {
        // nothing changed

    }

    UserDefaults.standard.set(currentVersion, forKey: "VersionOfLastRun")
    UserDefaults.standard.synchronize()
}

谢谢伙计 :) 运行得很好 - Ankit Kumar Gupta
2
这需要我从第一个版本开始设置,对吧?如果已经有一个版本,我想在即将推出的更新中测试新安装与更新怎么办呢?@Saggy - Jay Mutzafi
如果您已经发布了没有此代码的版本并且想要检测升级,则此操作将失败。 - Rajashekar
@Rajashekar:当然。如果你没有这个版本,这段代码在发布上是无法运行的。 - Saggy

4

针对Swift 3版本

 let currentVersion : String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String

let versionOfLastRun: String? = UserDefaults.standard.object(forKey: "VersionOfLastRun") as? String

if versionOfLastRun == nil {
     // First start after installing the app
} else if  !(versionOfLastRun?.isEqual(currentVersion))! {
      // App is updated
}

UserDefaults.standard.set(currentVersion, forKey: "VersionOfLastRun")
UserDefaults.standard.synchronize()

0

注意:

要获取任何键的本地化值,您应该使用CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), "CFBundleShortVersionString" as CFString)


0
请在NSUserDefaults中存储一个版本(参考@Nero的答案),以便检查可能的新安装和后续更新。
为了检查重新安装(在存储的version == nil的情况下),利用iOS 11引入的DeviceCheck API,该API公开了两个设备特定数据位,可以由应用程序设置和检索,但由Apple维护并跨卸载/重新安装持久化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接