I am trying to find a way in Swift to detect the first launch.
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")
}
firstLaunch
is an Optional. You're not grappling with that. Plus, it will be nil because you didn't register a value. –
Halflight boolForKey
does not return an optional but false if the value doesn't exist. –
Labonte boolForKey
. –
Halflight setValue
, as that take an AnyObject?
. –
Labonte objectForKey:
do return an Optional. But boolForKey:
has special behavior. So that was a good choice! –
Halflight if firstLaunch { println("Not first launch.") }
that doesn't make much sense ;-) –
Handcraft launchedBefore
or something. –
Labonte 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
}
}
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
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
}
}
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.
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
}
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
}
}
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.
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
}
}()
© 2022 - 2024 — McMap. All rights reserved.