如何在iPhone上检测应用程序的首次启动

168

如何检测首次启动

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // if very first launch than perform actionA
  // else perform actionB
}

什么是方法?


我认为https://dev59.com/2FXTa4cB1Zd3GeqP3aPb会对你有所帮助。 - Charan
17个回答

391
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    return YES;
}

我遇到了一个错误,因为该方法没有返回布尔值。如果我使用"return 0;"来解决这个错误,它会失败。 - mrEmpty
@mrEmpty 1. 这将返回 BOOL 类型。2. 如果返回 0 导致崩溃,那么错误肯定出现在你的代码中... 可能是其他地方出了严重问题。 - user529758
@H2CO3 - NSUserDefaults 不是一个常见的地方吗?如果另一个应用程序使用了我正在使用的相同“键”,会怎样呢? - Ziv Levy
6
不,用户默认设置以属性列表的形式在每个沙盒(即每个应用程序)中存储。 - user529758
4
它只适用于之前从未提交过的新应用程序。 - Elad
显示剩余2条评论

41

Swift 3, 4 中,可以尝试以下方法:

func isAppAlreadyLaunchedOnce()->Bool{
        let defaults = UserDefaults.standard
        
        if defaults.bool(forKey: "isAppAlreadyLaunchedOnce"){
            print("App already launched : \(isAppAlreadyLaunchedOnce)")
            return true
        }else{
            defaults.set(true, forKey: "isAppAlreadyLaunchedOnce")
            print("App launched first time")
            return false
        }
    }

Swift 2 中,请尝试以下内容:

func isAppAlreadyLaunchedOnce()->Bool{
    let defaults = NSUserDefaults.standardUserDefaults()
    
    if defaults.boolForKey("isAppAlreadyLaunchedOnce"){
        print("App already launched : \(isAppAlreadyLaunchedOnce)")
        return true
    }else{
        defaults.setBool(true, forKey: "isAppAlreadyLaunchedOnce")
        print("App launched first time")
        return false
    }
}

更新:- 对于 OBJ-C,我使用这个:

+ (BOOL)isAppAlreadyLaunchedOnce {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"isAppAlreadyLaunchedOnce"])
    {
        return true;
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isAppAlreadyLaunchedOnce"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        return false;
    }
}

Objective-C 参考文献: https://dev59.com/1mkw5IYBdhLWcg3wVpFi#9964400


35
我为此编写了一个小型库,它可以让我知道这是首次启动还是仅限于此版本以及用户安装过的任何先前版本。它在github上作为cocoapod提供,并受Apache 2许可证保护:GBVersionTracking 只需在application:didFinishLaunching:withOptions:中调用即可。
[GBVersionTracking track];

然后要检查是否为首次启动,只需在任何地方调用以下内容:

[GBVersionTracking isFirstLaunchEver];

同样地:

[GBVersionTracking isFirstLaunchForVersion];

[GBVersionTracking currentVersion];
[GBVersionTracking previousVersion];
[GBVersionTracking versionHistory];

1
这几乎是完美的!如果没有GBToolbox依赖和podspec,那就更棒了。 - Stian Høiland
4
GBToolbox的依赖已经被移除了,该库现在附带一个podspec(已发布到CocoaPods Specs仓库)。 - lmirosevic

14

适用于 Swift 3.0 - Swift 5

添加扩展(extension)

    extension UIApplication {
        class func isFirstLaunch() -> Bool {
            if !UserDefaults.standard.bool(forKey: "hasBeenLaunchedBeforeFlag") {
                UserDefaults.standard.set(true, forKey: "hasBeenLaunchedBeforeFlag")
                UserDefaults.standard.synchronize()
                return true
            }
            return false
        }
    }

然后在你的代码中

UIApplication.isFirstLaunch()

2
如果您在应用程序的多个位置请求它,那么对于第二个和后续的请求,它将返回FALSE,尽管它可能实际上是第一次运行。最好使用启动计数器。 - VyacheslavBakinkskiy
不再需要同步调用了 - Sentry.co

8

Xcode 7和Swift 2.0的另一个想法是使用扩展功能。

extension NSUserDefaults {
    func isFirstLaunch() -> Bool {
        if !NSUserDefaults.standardUserDefaults().boolForKey("HasAtLeastLaunchedOnce") {
            NSUserDefaults.standardUserDefaults().setBool(true, forKey: "HasAtLeastLaunchedOnce")
            NSUserDefaults.standardUserDefaults().synchronize()
            return true
        }
        return false
    }
}

现在您可以在应用的任何位置进行编写。
if NSUserDefaults.standardUserDefaults().isFirstLaunch() {
    // do something on first launch
}

我个人更喜欢像这样扩展UIApplication的方式:

我个人更喜欢像这样扩展UIApplication的方式:

extension UIApplication {
    class func isFirstLaunch() -> Bool {
        if !NSUserDefaults.standardUserDefaults().boolForKey("HasAtLeastLaunchedOnce") {
            NSUserDefaults.standardUserDefaults().setBool(true, forKey: "HasAtLeastLaunchedOnce")
            NSUserDefaults.standardUserDefaults().synchronize()
            return true
        }
        return false
    }
}

因为函数调用更具描述性:

if UIApplication.isFirstLaunch() {
    // do something on first launch
}

8
您可以使用下面的静态方法来实现它:
+ (BOOL)isFirstTime{
    static BOOL flag=NO;
    static BOOL result;

    if(!flag){
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"hasLaunchedOnce"]){
            result=NO;
        }else{
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"hasLaunchedOnce"];
            [[NSUserDefaults standardUserDefaults] synchronize];
            result=YES;
        }

        flag=YES;
    }
    return result;
}

请记住,如果您希望此方法是线程安全的,您需要对其进行锁定。 - Mati Bot
9
我知道,但这种方法不行。当标志为NO时,两个线程可以到达if(!flag){。它们将进入if块。其中一个将到达内部的else并设置NSUserDefaults,而第二个将通过“hasLaunchOnce”(因为第一个线程已经声明了它)并将结果设置为NO。那意味着你可能会获得错误的值。 - Mati Bot

5

在启动时,您需要保存某些内容并检查其是否存在。如果不存在,则表示这是第一次。 "某些内容"可以是文件、数据库条目、用户默认设置中的设置等。


4

这很简单,只需要六行代码即可完成。

将此代码添加到应用程序启动首选项或其他任何需要测试应用程序是否首次运行的位置将非常有用。

//These next six lines of code are the only ones required! The rest is just running      code when it's the first time.
//Declare an integer and a default.
NSUserDefaults *theDefaults;
int  launchCount;
//Set up the properties for the integer and default.
theDefaults = [NSUserDefaults standardUserDefaults];
launchCount = [theDefaults integerForKey:@"hasRun"] + 1;
[theDefaults setInteger:launchCount forKey:@"hasRun"];
[theDefaults synchronize];

//Log the amount of times the application has been run
NSLog(@"This application has been run %d amount of times", launchCount);

//Test if application is the first time running
if(launchCount == 1) {
    //Run your first launch code (Bring user to info/setup screen, etc.)
    NSLog(@"This is the first time this application has been run";
}

//Test if it has been run before
if(launchCount >= 2) {
    //Run new code if they have opened the app before (Bring user to home screen etc.
    NSLog(@"This application has been run before);
}

注意:不要在首选项中使用布尔值,只需使用整数。当未定义时,它们默认为零。

此外,[theDefaults synchronize];行并非必需,但我发现在数百个设备上运行数百次应用程序时,结果并不总是可靠的,而且这是更好的做法。


你的例子是可行的,但OP只是想知道它是否是第一次启动。一个布尔值就足够了。如果想知道用户打开应用程序的次数,你的代码是有意义的。 - tilo

3

快速简便的功能

- (BOOL) isFirstTimeOpening {
    NSUserDefaults *theDefaults = [NSUserDefaults standardUserDefaults];
    if([theDefaults integerForKey:@"hasRun"] == 0) {
        [theDefaults setInteger:1 forKey:@"hasRun"];
        [theDefaults synchronize];
        return true;
    }
    return false;
}

3

第一次将布尔键存储在NSUserDefaults中,它将是“否”,然后您将其更改为“是”,并保持这种状态直到应用程序删除或重新安装,那么它将再次是第一次。


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