Detect first launch of iOS app

IosSwift

Ios Problem Overview


I am trying to find a way in Swift to detect the first launch.

Ios Solutions


Solution 1 - Ios

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

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

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

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

Solution 5 - Ios

Use NSUserDefaults. Register a BOOL key with a value of false. Read the key at launch time; if it's false, set it to true and show the welcome. Next launch, it will be true, you won't show the welcome, problem solved.

Solution 6 - Ios

In case of Swift In applicationdidFinishLaunchingWithOptions in AppDelegate Add:

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

And Use this wherever you want to.

let isFirstLaunch = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool

    if isFirstLaunch {
    //It's the initial launch of application.
    }
    else {
    // not initial launch
    }

Solution 7 - Ios

I did an edit of n13's post. This code seems cleaner to me. You can call as a class or instance function.

Also, according to apple docs you shouldn't call synchronize() since it's called periodically, unless the app is about to close. I have it called in the AppDelegate in applicationDidEnterBackground(). 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
  }
}

Solution 8 - Ios

you can use UserDefaults to store the times that App has opened

First:

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
}

each time the App is open, you should add the property currentTimesOfOpenApp, so modify this property in the function func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

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

in addition, when the app is closed, you should save the currentTimesOfOpenApp, that is important!

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

Second:

if you want to show the times, you can get this value form UserDefaults to display it on the Label.

ViewController.swift

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

the App is open every time, the currentTimesOfOpenApp will be increase. if you delete the App, this value will be reset as 1.

Solution 9 - Ios

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJulian StellaardView Question on Stackoverflow
Solution 1 - IosJon ShierView Answer on Stackoverflow
Solution 2 - Iosn13View Answer on Stackoverflow
Solution 3 - IosRomanView Answer on Stackoverflow
Solution 4 - IosjaloneView Answer on Stackoverflow
Solution 5 - IosmattView Answer on Stackoverflow
Solution 6 - IosSreedeepkesav M SView Answer on Stackoverflow
Solution 7 - IosHannyView Answer on Stackoverflow
Solution 8 - IosFrank LiView Answer on Stackoverflow
Solution 9 - IosRuslanView Answer on Stackoverflow