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


Answers:


386
- (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导致此崩溃,则说明存在严重错误-其他地方。

@ H2CO3-不NSUserDefaults常见吗?如果另一个应用程序使用与我相同的“密钥”怎么办?
Ziv Levy

6
@ZivLevy不,用户默认值是基于每个沙盒(=每个应用程序)存储在属性列表中的。

2
它仅适用于从未提交过的新应用。
Elad

36

Swift 3、4中尝试以下操作:

func isAppAlreadyLaunchedOnce()->Bool{
        let defaults = UserDefaults.standard

        if let isAppAlreadyLaunchedOnce = defaults.string(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 let isAppAlreadyLaunchedOnce = defaults.stringForKey("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;
    }
}

OBJ-C的参考:https : //stackoverflow.com/a/9964400/3411787


32

为此,我编写了一个小型库。它让我知道这是有史以来第一次启动,还是仅针对此版本,以及用户已安装的任何过去版本。根据Apache 2许可,它可以作为coapapod在github上提供:GBVersionTracking

你只是叫这个 application:didFinishLaunching:withOptions:

[GBVersionTracking track];

然后检查这是否是第一次启动,只需在任何地方调用此命令:

[GBVersionTracking isFirstLaunchEver];

并且类似地:

[GBVersionTracking isFirstLaunchForVersion];

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

1
这几乎是完美的!如果没有GBToolbox依赖项和podspec,本来很棒。
StianHøiland2013年

4
@StianHøilandGBToolbox依赖关系消失了,库附带了一个podspec(已发布到CocoaPods规格存储库中)。
lms 2014年

9

适用于Swift 3.0-Swift 5

添加扩展名

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

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扩展:

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

请记住,如果您希望此方法是线程安全的,则需要锁定此方法。
马蒂·博特

9
我知道,但是这种方法不是。当标志为NO时,2个线程可以到达if(!flag){ 他们将进入if块内。其中一个将进入内部else并设置NSUserDefaults,第二个将传递“ hasLaunchOnce”(因为第一个线程声明了它)并将结果设置为NO。这意味着您可以获得错误的值。
Mati Bot 2013年


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

PS 请勿在首选项中使用bool只是坚持整数。未定义时,它们默认为零。

另外,[theDefaults synchronize];不需要这条线,但是我发现,当一个应用在数百个设备上运行数百次时,结果并不总是可靠的,此外,这是更好的做法。


您的示例可行,但是OP要求的只是它是否是第一次启动。布尔对此很好。如果您想知道用户打开应用程序的次数,则您的代码很有意义。
tilo

3

第一次将bool密钥存储在NSUserDefaults中,将其更改为yes,并保持该状态不变,直到应用删除或重新安装,这将是第一次。


3

快速简便的功能

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

3

对于Xcode 7中的Swift 2.0。在AppDelegate.swift文件中:

import UIKit

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool
{
    return true
}


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    didFinishLaunchingOnce()
    return true
}

func didFinishLaunchingOnce() -> Bool
{
    let defaults = NSUserDefaults.standardUserDefaults()

    if let hasBeenLauncherBefore = defaults.stringForKey("hasAppBeenLaunchedBefore")
    {
        //print(" N-th time app launched ")
        return true
    }
    else
    {
        //print(" First time app launched ")
        defaults.setBool(true, forKey: "hasAppBeenLaunchedBefore")
        return false
    }
}

}

2

迅速

struct Pref {
    static let keyFirstRun = "PrefFirstRun"
    static var isFirstRun: Bool {
        get {
            return UserDefaults.standard.bool(forKey: keyFirstRun)
        }
        set {
            UserDefaults.standard.set(newValue, forKey: keyFirstRun)
        }
    }
}

在应用启动时注册默认值:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let prefs: [String:Any] = [
            Pref.keyFirstRun: true
            ...
        ]

        UserDefaults.standard.register(defaults: prefs)

应用终止时的明确价值:

func applicationWillTerminate(_ application: UIApplication) {
        Pref.isFirstRun = false

检查值:

 if Pref.isFirstRun {
    ... do whatever 

2

我建议尽快使用一个全局常量,该常量可以在任何范围之外(例如在App委托上方)轻松完成。因此,只要应用未终止,它将被设置为正确的值。如果应用程序进入后台运行,它将仍然返回相同的值。只有完全重新启动该应用程序,该值才会更改。

let isFirstLaunch: Bool = {
    if !UserDefaults.standard.bool(forKey: "hasBeenLaunchedBeforeFlag") {
        UserDefaults.standard.set(true, forKey: "hasBeenLaunchedBeforeFlag")
        UserDefaults.standard.synchronize()
        return true
    }
    return false
}()

但老实说,最好跟踪应用已至少发送到后台一次的事实。在这种情况下,我更喜欢在UIApplication上使用扩展,并在applicationDidEnterBackground方法中设置标志,以便:

extension UIApplication {
    private static let isFirstLaunchKey = "isFirstLaunchKey"
    static var isFirstLaunch: Bool {
        return !UserDefaults.standard.bool(forKey: isFirstLaunchKey)
    }
    static func didEnterBackground() {
        if isFirstLaunch {
            UserDefaults.standard.set(true, forKey: isFirstLaunchKey)
            UserDefaults.standard.synchronize()
        }
    }
}

然后在您的应用程序委托或场景委托中

func sceneDidEnterBackground(_ scene: UIScene) {
        UIApplication.didEnterBackground()
    }

2

Swift 5 iOS 13。

我喜欢Chris Fremgen的便捷。所以我更新了它。

func isFirstTimeOpening() -> Bool {
  let defaults = UserDefaults.standard

  if(defaults.integer(forKey: "hasRun") == 0) {
      defaults.set(1, forKey: "hasRun")
      return true
  }
  return false

}

2

已针对XCode 11Swift 5更新

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

然后你称它为

UIApplication.isFirstLaunch()

0

NSUserDefaults +宏

最好的方法是使用NSUserDefaults和保存BOOL变量。如上所述,以下代码可以正常工作:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:[NSNumber numberWithBool:true] forKey:@"~applicationHasLaunchedBefore"];
[userDefaults synchronize];

您还可以如下创建,以轻松检查它是否是首次启动

#define kApplicationHasLaunchedBefore [[NSUserDefaults standardUserDefaults] objectForKey:@"~applicationHasLaunchedBefore"]

然后就这样使用它

if (kApplicationHasLaunchedBefore) {
    //App has previously launched
} else {
    //App has not previously launched
}

0

这是在Swift 5.0中工作的答案。与@Zaid Pathan的答案相比,改进之处在于没有隐藏的合同。如果在调用之前没有setFirstAppLaunch()完全调用一次isFirstAppLaunch()则会得到一个断言错误(仅在调试模式下)。

fileprivate struct _firstAppLaunchStaticData {
    static var alreadyCalled = false
    static var isFirstAppLaunch = true
    static let appAlreadyLaunchedString = "__private__appAlreadyLaunchedOnce"
}

func setFirstAppLaunch() {
    assert(_firstAppLaunchStaticData.alreadyCalled == false, "[Error] You called setFirstAppLaunch more than once")
    _firstAppLaunchStaticData.alreadyCalled = true
    let defaults = UserDefaults.standard

    if defaults.string(forKey: _firstAppLaunchStaticData.appAlreadyLaunchedString) != nil {
        _firstAppLaunchStaticData.isFirstAppLaunch = false
    }
    defaults.set(true, forKey: _firstAppLaunchStaticData.appAlreadyLaunchedString)
}

func isFirstAppLaunch() -> Bool {
    assert(_firstAppLaunchStaticData.alreadyCalled == true, "[Error] Function setFirstAppLaunch wasn't called")
    return _firstAppLaunchStaticData.isFirstAppLaunch
}

然后,您只需要setFirstAppLaunch()在应用程序的开始以及isFirstAppLaunch()需要检查是否已调用应用程序时调用该函数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.