6

How would I check if it is the first launch of of my application using NSUserDefaults and running some code for the first time my app opens?

jscs
  • 63,694
  • 13
  • 151
  • 195
atomikpanda
  • 1,845
  • 5
  • 33
  • 47

4 Answers4

20

This should point you in the right direction:

static NSString* const hasRunAppOnceKey = @"hasRunAppOnceKey";
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:hasRunAppOnceKey] == NO)
{
    // Some code you want to run on first use...
    [defaults setBool:YES forKey:hasRunAppOnceKey];
}
Matt Wilding
  • 20,115
  • 3
  • 67
  • 95
  • 4
    Unlike iOS, on OSX NSUserDefaults is not deleted when the app is deleted. As @ctrahey suggested, storing a bool value in another plist file would be a better way. – erkanyildiz Dec 26 '12 at 11:50
  • 1
    @erkanyildiz That's a good point. I didn't even notice the `osx` tag in the question. – Matt Wilding Jan 30 '13 at 20:24
  • 1
    any idea where to store plist file, so that it also deleted along with application deletion. – Usman Nisar Sep 11 '13 at 09:53
2

The NSUserDefaults answer is the first thing that popped in my head, but upon reflection I will make another suggestion. A bit more work, but it's worth considering. The motive is: sometimes when troubleshooting an app, Apple recommends deleting that app's plist file. It's a fairly ubiquitous troubleshooting technique. I would recommend storing your boolean in your plist file instead of NSUserDefaults.

Disclaimer: I only do iOS development, so I'm not sure how NSUserDefaults and plists interact on the Mac, and I don't know what all is involved in getting your plist to live in ~/Library/Application\ Support/Preferences/com.mycompany.MyAppName.plist

Anyway, I imagine what this requires is having some code which can actually author a "fresh" plist (probably a copy from a template file in your bundle), and you app does this if it launches and does not see a plist. The default plist should not include the flag which lets your users skip the 'first time' code, but if they have opened the app before, and then delete the plist, they should get default behavior back.

This is an important behavior to support where possible, to aide our users if our app ever gives them trouble.

Chris Trahey
  • 18,202
  • 1
  • 42
  • 55
2
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"hasBeenLaunched"]) {
    // Run code on the first launch only ...
    [defaults setBool:YES forKey:@"hasBeenLaunched"];
}

You can use NSUserDefaults to save bools, integers, objects into the program and have them available whenever you open it. You can use 'boolForKey' to set a flag called "hasBeenLaunched". By default, this value will be NO when not set. Once you change it to YES, the code in the if condition will never be executed again.

Omar
  • 105
  • 4
  • 1
    Maybe it is helpful for inexperienced programmers to provide a short exlpaination of what your code does. – Jens Dec 26 '14 at 23:14
  • Right! I thought it's self explanatory and simple, but I guess a small description won't harm. Thanks. – Omar Dec 27 '14 at 06:06
1

In your main controller class, implement something like this:

static NSString * const MDFirstRunKey  = @"MDFirstRun";


@implementation MDAppController

+ (void)initialize {
   NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
   [defaults setObject:[NSNumber numberWithBool:YES] forKey:MDFirstRunKey];
   [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
   // the following if on Mac and is necessary:
   [[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:defaults];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification {

  BOOL firstRun = [[[NSUserDefaults standardUserDefaults]
                      objectForKey:MDFirstRunKey] boolValue];

  if (firstRun) {
     // do something

     [[NSUserDefaults standardUserDefaults] setObject:
                [NSNumber numberWithBool:NO] forKey:MDFirstRunKey];

  } else {
     // do something else

  }
}

@end

The +initialize class method is called before an instance of the class it's found in is created; in other words, it is called very early on, and is a good place to set up your default values.

See Preferences and Settings Programming Guide: Registering Your App's Default Preferences for more info.

NSGod
  • 22,699
  • 3
  • 58
  • 66