【问题标题】:Detect first launch of iOS app [duplicate]检测iOS应用程序的首次启动[重复]
【发布时间】:2014-11-29 23:02:43
【问题描述】:

我正在尝试在 Swift 中找到一种方法来检测首次启动。

【问题讨论】:

  • “我在 Stackoverflow 上看到了一个主题,但它已经过时了(目标 C)。”正如以下所有答案所示,无论您使用 Objective-C 还是 Swift 编码,您的问题的解决方案(并且已经有一段时间)几乎相同。

标签: ios swift


【解决方案1】:

通常,您会向 NSUserDefaults 写入一个值,以指示应用之前已启动。

let launchedBefore = NSUserDefaults.standardUserDefaults().boolForKey("launchedBefore")
if launchedBefore  {
    print("Not first launch.")
}
else {
    print("First launch, setting NSUserDefault.")
    NSUserDefaults.standardUserDefaults().setBool(true, forKey: "launchedBefore")
}

更新 - Swift 3

let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore")
if launchedBefore  {
    print("Not first launch.")
} else {
    print("First launch, setting UserDefault.")
    UserDefaults.standard.set(true, forKey: "launchedBefore")
}

【讨论】:

  • 这不会像你写的那样工作。 firstLaunch 是可选的。你不是在努力解决这个问题。另外,它将为零,因为您没有注册值。
  • 它工作得很好,因为我已经测试过了。 boolForKey 不返回可选值,但如果值不存在则返回 false。
  • 好的!那就好了。 :) 我没有意识到boolForKey 的巧妙改进。
  • if firstLaunch { println("Not first launch.") } 这没有多大意义 ;-)
  • @TimCastelijns 是的,我想应该是launchedBefore 什么的。
【解决方案2】:

我总是需要这个,所以我把它放在一个类别中

一般用法:

let isFirstLaunch = UserDefaults.isFirstLaunch()

在您的 AppDelegate 中使用

// use this if you need to refer to it later
var optionallyStoreTheFirstLaunchFlag = false

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        optionallyStoreTheFirstLaunchFlag = UserDefaults.isFirstLaunch()
   // .. do whatever else

    return true
}

一些重要的注意事项:

  • 此标志仅在第一次调用时设置。如果你想知道 关于在不同屏幕上多次首次启动, 根据 'optionallyStoreTheFirstLaunchFlag' 示例。
  • 在 iOS 中,应用程序通常永远不会关闭。应用程序是后台的,前台的, 状态保存到闪存,但它们只有在它们被重新启动时才会重新启动 用户强制关机(罕见)或用户重新启动手机。 所以如果你把它存储在一个变量中,它可能会一直存在 需很长时间。显示全部后手动重置 教程屏幕等等。

斯威夫特 4

将以下内容放入 UserDefaults+isFirstLaunch.swift 中

extension UserDefaults {
    // check for is first launch - only true on first invocation after app install, false on all further invocations
    // Note: Store this value in AppDelegate if you have multiple places where you are checking for this flag
    static func isFirstLaunch() -> Bool {
        let hasBeenLaunchedBeforeFlag = "hasBeenLaunchedBeforeFlag"
        let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunchedBeforeFlag)
        if (isFirstLaunch) {
            UserDefaults.standard.set(true, forKey: hasBeenLaunchedBeforeFlag)
            UserDefaults.standard.synchronize()
        }
        return isFirstLaunch
    }
}

【讨论】:

  • 仅供其他用户参考,您需要在 viewDidAppear 部分添加: if isFirstLaunch { instructions here } else { print ("Not first launch")}
  • 你可以以任何你喜欢的方式使用它,但请记住它只会在第一次调用时产生一个“真实”值。如果它在多个视图中使用,则需要注意这一点。
  • 如果您希望它在整个第一个应用生命周期直到终止之前始终正确,请参阅下面的答案。
  • 此外,如果出于某种原因您在第一次启动时没有调用该方法,它会在第二次启动时产生“真”。
  • @MihaiDamian 我不确定你在说什么。如果您不调用它,它将无法正常工作。就像所有代码一样?!也许我应该澄清一下用法——也许你有一个在启动时没有被调用的代码路径?
【解决方案3】:

斯威夫特 3

extension UserDefaults {

     var hasLaunchBefore: Bool {
           get {
             return self.bool(forKey: #function)
           }
           set {
             self.set(newValue, forKey: #function)
           }
     }
}

Swift 5(属性包装器)

用户默认包装器:

@propertyWrapper
struct UserDefaultWrapper<T> {
    let key: String
    let defaultValue: T

    init(_ key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }

    var wrappedValue: T {
        get {
            return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
        }
        set {
            UserDefaults.standard.set(newValue, forKey: key)
        }
    }
}

用户默认存储:

struct UserDefaultsStore {
    @UserDefaultWrapper("has_launch_before", defaultValue: false)
    static var hasLaunchBefore: Bool
}

用法:

UserDefaultsStore.hasLaunchBefore = false

【讨论】:

  • 对于属性包装器尝试 +1 虽然我没有尝试过。 :)
【解决方案4】:

为了

  • 让该方法在整个首次启动期间始终返回 true
  • 成为 UIApplication 的扩展

只需将它用作UIApplication.isFirstLaunch()确保在第一次执行期间至少到达一次

斯威夫特 3

import UIKit

private var firstLaunch : Bool = false

extension UIApplication {

    static func isFirstLaunch() -> Bool {
        let firstLaunchFlag = "isFirstLaunchFlag"
        let isFirstLaunch = UserDefaults.standard.string(forKey: firstLaunchFlag) == nil
        if (isFirstLaunch) {
            firstLaunch = isFirstLaunch
            UserDefaults.standard.set("false", forKey: firstLaunchFlag)
            UserDefaults.standard.synchronize()
        }
        return firstLaunch || isFirstLaunch
    }
}

斯威夫特 2

import UIKit

private var firstLaunch : Bool = false

extension UIApplication {

    static func isFirstLaunch() -> Bool {
        let firstLaunchFlag = "isFirstLaunchFlag"
        let isFirstLaunch = NSUserDefaults.standardUserDefaults().stringForKey(firstLaunchFlag) == nil
        if (isFirstLaunch) {
            firstLaunch = isFirstLaunch
            NSUserDefaults.standardUserDefaults().setObject("false", forKey: firstLaunchFlag)
            NSUserDefaults.standardUserDefaults().synchronize()
        }
        return firstLaunch || isFirstLaunch
    }
}

【讨论】:

  • 为什么在 userdefaults 中存储字符串而不是布尔值? :O
  • 我刚刚编辑了 n13 答案,因为有人要求它。还有更多需要改进的地方,但我想这只是为了避免这种情况stackoverflow.com/a/20934386/691977
  • 我的 Swift 版本存储一个布尔值 FYI ;)
  • 这个答案应该完全重写:/
【解决方案5】:

使用NSUserDefaults。注册一个值为false 的BOOL 键。在启动时读取密钥;如果是false,请将其设置为true 并表示欢迎。下次启动,会是true,你不会显示欢迎,问题解决了。

【讨论】:

  • 重置密钥怎么样?假设我推出了我的新版本的应用程序并用户对其进行了更新,那么在这种情况下,我还想执行一项任务(例如,显示欢迎消息),那么需要做什么?
【解决方案6】:

我编辑了 n13 的帖子。这段代码对我来说似乎更干净。您可以作为类或实例函数调用。

此外,根据苹果文档,您不应调用 synchronize(),因为它会定期调用,除非应用程序即将关闭。我在 applicationDidEnterBackground() 的 AppDelegate 中调用了它。 https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/#//apple_ref/occ/instm/NSUserDefaults/synchronize

    if NSUserDefaults().isFirstLaunchForUser("me") {
        print("First launch")
    } else {
        print("Not first launch")
    }


    if NSUserDefaults.isFirstLaunch() {
        print("First launch")
    } else {
        print("Not first launch")
    }



extension NSUserDefaults {

  static func isFirstLaunch() -> Bool {
      let firstLaunchFlag = "FirstLaunchFlag"

      if !standardUserDefaults().boolForKey(firstLaunchFlag) {
          standardUserDefaults().setBool(true, forKey: firstLaunchFlag)
          // standardUserDefaults().synchronize()
          return true
      }
      return false
    }

  // For multi user login
  func isFirstLaunchForUser(user: String) -> Bool {

      if !boolForKey(user) {
          setBool(true, forKey: user)
          // synchronize()
          return true
      }
      return false
  }
}

【讨论】:

    【解决方案7】:

    如果是 Swift 在 AppDelegate 中的 applicationdidFinishLaunchingWithOptions 添加:

    if UserDefaults.standard.bool(forKey: "isFirstLaunch") {
                UserDefaults.standard.set(true, forKey: "isFirstLaunch")
                UserDefaults.standard.synchronize()
            }
    

    并在任何你想使用的地方使用它。

    let isFirstLaunch = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool
    
        if isFirstLaunch {
        //It's the initial launch of application.
        }
        else {
        // not initial launch
        }
    

    【讨论】:

      【解决方案8】:

      您可以使用 UserDefaults 来存储 App 打开的时间

      第一:

      AppDelegate.swift

      let userDefaults = UserDefaults.standard
      var currentTimesOfOpenApp:Int = 0
      
      func saveTimesOfOpenApp() -> Void {
          userDefaults.set(currentTimesOfOpenApp, forKey: "timesOfOpenApp")
      }
      
      func getCurrentTimesOfOpenApp() -> Int {
          return userDefaults.integer(forKey: "timesOfOpenApp") + 1
      }
      

      App每次打开都要添加属性currentTimesOfOpenApp,所以在函数func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]中修改这个属性?) -> 布尔型

      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
              self.currentTimesOfOpenApp = getCurrentTimesOfOpenApp()
              return true
          }
      

      另外,当应用关闭时,你应该保存currentTimesOfOpenApp,这很重要!

      func applicationWillTerminate(_ application: UIApplication) {
              saveTimesOfOpenApp()
              self.saveContext()
          }
      

      第二:

      如果你想显示时间,你可以从 UserDefaults 中获取这个值来显示在 Label 上。

      ViewController.swift

      let delegate = UIApplication.shared.delegate as! AppDelegate
      let times = delegate.currentTimesOfOpenApp
      timesToOpenAppLabel.text = "\(times)"
      

      App 每次打开,currentTimesOfOpenApp 都会增加。如果您删除应用程序,该值将被重置为 1。

      【讨论】:

        【解决方案9】:
        let applicationLaunchedOnce: Bool = {
                let launchedOnce = NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsService.ApplicationLaunchedOnce)
                if launchedOnce {
                    return launchedOnce
                } else {
                    NSUserDefaults.standardUserDefaults().setBool(true, forKey: UserDefaultsService.ApplicationLaunchedOnce)
                    NSUserDefaults.standardUserDefaults().synchronize()
                    return false
                }
            }()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-23
          • 1970-01-01
          • 2013-11-19
          • 1970-01-01
          • 2012-10-10
          • 1970-01-01
          • 2020-07-25
          • 1970-01-01
          相关资源
          最近更新 更多