Detect first launch of iOS app [duplicate]

Solution 1:

Typically you would write a value to NSUserDefaults to indicate that an app has launched before.

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

UPDATE - 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")
}

Solution 2:

I kinda always need this so I put it in a category

General Usage:

let isFirstLaunch = UserDefaults.isFirstLaunch()

Usage inside your 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
}

Some important considerations:

  • This flag is only set on the first invocation. If you want to know about the first launch multiple times throughout different screens, set a variable you can later refer to, as per the 'optionallyStoreTheFirstLaunchFlag' example.
  • In iOS, apps are usually never shut down. Apps are backgrounded, foregrounded, state-saved to flash memory, but they are only relaunched if they're force shutdown by the user (rare) or the user restarts their phone. So if you store it in a variable, it could potentially stick around for a long time. Manually reset it once you're done with showing all the tutorial screens and whatnot.

Swift 4

Put the following in 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
    }
}

Solution 3:

Swift 3

extension UserDefaults {

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

Swift 5 (Property wrappers)

UserDefaultWrapper:

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

UserDefaultsStore:

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

Usage:

UserDefaultsStore.hasLaunchBefore = false

Solution 4:

I refined a bit user n13 answer in order to

  • have the method always return true during the whole first launch
  • be an extension to UIApplication

Just use it wherever you want as UIApplication.isFirstLaunch() and be sure to reach it at least once during first execution.

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

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