16

I would like to display a welcome screen when a user opens my app for the first time. What method is there to check the first launch of an app in Swift?

Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
Natanel
  • 1,706
  • 1
  • 18
  • 19

9 Answers9

40

Swift 4 and higher

You can use this anywhere to verify that the user is seeing this view for the first time.

func isAppAlreadyLaunchedOnce() -> Bool {
    let defaults = UserDefaults.standard
    if let _ = defaults.string(forKey: "isAppAlreadyLaunchedOnce") {
        print("App already launched")
        return true
    } else {
        defaults.set(true, forKey: "isAppAlreadyLaunchedOnce")
        print("App launched first time")
        return false
    }
}

Note: This method would return false after user re-installs app and launch first time.

Jonas Deichelmann
  • 3,513
  • 1
  • 30
  • 45
16

Try this for Swift 2 and below

func isAppAlreadyLaunchedOnce()->Bool{
    let defaults = NSUserDefaults.standardUserDefaults()

    if let isAppAlreadyLaunchedOnce = defaults.stringForKey("isAppAlreadyLaunchedOnce"){
        println("App already launched")
        return true
    }else{
        defaults.setBool(true, forKey: "isAppAlreadyLaunchedOnce")
        println("App launched first time")
        return false
    }
}
Jonas Deichelmann
  • 3,513
  • 1
  • 30
  • 45
Mohammad Zaid Pathan
  • 16,304
  • 7
  • 99
  • 130
  • The original version of this function may return true when it should return false and the other way around; I'm not sure; using it in XCode 9 Beta (for Swift 4) the editor made updated name and logic suggestions which led to that being the case. – Alex Hall Jul 05 '17 at 20:32
  • Thanks @AlexHall for pointing out, will update func so that it will work without issues. – Mohammad Zaid Pathan Oct 03 '17 at 05:23
9

Since NSUserDefaults for an app are erased when uninstalling the app, you could try testing for the existence of a certain value when the app launches.

If the value exists, the app had already been installed. If not, this is the first time the app is launched, and you set that value.

Gilles Major
  • 489
  • 1
  • 3
  • 12
3

SWIFT :

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

OBJECTIVE - C :

if ([[NSUserDefaults standardUserDefaults] boolForKey:@"isAppAlreadyLaunchedOnce"])
{
    return true;
}
else
{
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isAppAlreadyLaunchedOnce"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    return false;
}
  • 1
    Don't use `-[NSUserDefaults synchronize]`. From [Apple's documentation](https://developer.apple.com/documentation/foundation/nsuserdefaults/1414005-synchronize?language=objc) _"this method is unnecessary and shouldn't be used."_ – Ashley Mills Oct 11 '18 at 14:19
3

Swift 5

let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore") 
   
if launchedBefore {
// Code if has launched before
} else {
UserDefaults.standard.set(true, forKey: "launchedBefore")
// Code if not has launched before
}
Pramodya Abeysinghe
  • 1,098
  • 17
  • 13
2

I often found userDefault inaccessible due to some bugs for Apples data protection policy in my app, So I changed my strategy to detect first launch with below

if ( fileExists( dummyFilePath ) == NO ) {
    createFileAt( dummyFilePath )
    // This is first launch
}
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
1

Objective-C version of Jon Shier's answer:

BOOL isAppLaunched = [[NSUserDefaults standardUserDefaults] boolForKey:@"launchedBefore"];
if (isAppLaunched) {
    NSLog(@"Not first launch.");
}
else {
    NSLog(@"First launch, setting NSUserDefault.");
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"launchedBefore"];
}
Mahmut Acar
  • 713
  • 2
  • 7
  • 26
1

A slight semantic modification of Jonas Deichelmann's answer, clarifying a few things:

  • The function name "establishUserDefaultsHaveBeenVerifed" provides a suggestion that the userDefaults aren't just being checked, but may also be written to.
  • The key previously suggested, "isAppAlreadyLaunchedOnce", describes something the function itself has no control over; that key will only correctly describe the launch state if the function is called at the right time by other code, which again, the function itself can't control. Using the key "userDefaultsHaveBeenVerified" instead makes clear that the only thing the function verifies is that it itself has been run before.
  • The print statements make clear that this function is only verifying if it has been run since last installation, not whether or not it has ever been run on this device.

    func establishUserDefaultsHaveBeenVerifed()->Bool{
         let defaults = UserDefaults.standard
         if let _ = defaults.string(forKey: "userDefaultsHaveBeenVerified"){
             print("user defaults were already verified")
             return true
          }else{
             defaults.set(true, forKey: "userDefaultsHaveBeenVerified")
             print("verified user defaults for first time since app was installed")
             return false
          }
     }
    
Le Mot Juiced
  • 3,761
  • 1
  • 26
  • 46
0

When you need to do something when it is NOT a first session (for example, show rate app):

@UserDefault(key: UDKey.isFirstSession, defaultValue: true)
static var isFirstSession: Bool

func applicationWillTerminate(_ application: UIApplication) {
    // When app is terminated, next sessions are not first anymore
    UserDefaults.isFirstSession = false
}

What is @UserDefault:

@propertyWrapper
struct UserDefault<Value> {
    let key: String
    let defaultValue: Value
    var container: UserDefaults = .standard

    var wrappedValue: Value {
        get {
            return container.object(forKey: key) as? Value ?? defaultValue
        }
        set {
            container.set(newValue, forKey: key)
        }
    }
}

What is UDKey:

enum UDKey {
    static let isFirstSession = "isFirstSession"
}
Denis Kutlubaev
  • 15,320
  • 6
  • 84
  • 70