检测iOS应用程序的首次启动[重复]

Posted

技术标签:

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

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

【问题讨论】:

“我在 *** 上看到了一个主题,但它已经过时了(目标 C)。”正如以下所有答案所示,无论您使用 Objective-C 还是 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 答案,因为有人要求它。还有更多需要改进的地方,但我想这只是为了避免这种情况***.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
        
    ()

【讨论】:

以上是关于检测iOS应用程序的首次启动[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 iCloud 环境中检测应用程序 (IOS/OSX) 的首次运行

如何设置 iOS 应用程序的首次启动

仅为 AppDelegate.m iOS 中的首次启动设置特定方向

如何检测 iOS App 是由特定用户(不是在特定设备上)首次启动的?

Xcode UI 测试:如何测试应用程序的首次启动

区分 UI 测试的首次启动