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