13

I built an application using Xcode 4.5 with storyboards. The first time the app launches I want the initial view controller to appear with terms and conditions that must be accepted to proceed. After that, I want the app to launch and skip over the first view controller and go to the second one.

I know I have to use the NSUserDefaults class and something to the effect of: if ([[NSUserDefaults standard...] boolForKey:@"iHaveAcceptedTheTerms"])

But I have never used this class before and have no idea how to implement this code. Can someone share the specifics of how to do this?

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
jac300
  • 5,182
  • 14
  • 54
  • 89

4 Answers4

14

In the interests of keeping this question up-to-date, here is a Swift version of the accepted answer.


STEP 1

In your App Delegate, add the following function.

func applicationDidFinishLaunching(application: UIApplication) {
    if !NSUserDefaults.standardUserDefaults().boolForKey("TermsAccepted") {
        NSUserDefaults.standardUserDefaults().setBool(false, forKey: "TermsAccepted")
    }
} 

This will essentially set your TermsAccepted Bool to false if this is the first launch (as Bools are false by default).


STEP 2

In your root view controller (the view controller which loads when your app is launched), you must have a way to see if the terms have been accepted or not and act accordingly.

Add the following function.

override func viewDidAppear(animated: Bool) {
    if NSUserDefaults.standardUserDefaults().boolForKey("TermsAccepted") {
        // Terms have been accepted, proceed as normal
    } else {
        // Terms have not been accepted. Show terms (perhaps using performSegueWithIdentifier)
    }
}

STEP 3

Once the user accepts your conditions, you want to change your TermsAccepted Bool to true. So in the body of the method which handles the acceptance of the terms, add the following line.

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "TermsAccepted")

I hope this helps!

Loic

Loic Verrall
  • 985
  • 15
  • 25
10

You put in in your AppDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  

//first-time ever defaults check and set
if([[NSUserDefaults standardUserDefaults] boolForKey:@"TermsAccepted"]!=YES)
{
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"TermsAccepted"];
}

Then you implement in your rootViewController the terms and conditions and a way to accept it. You will have to check if the terms are accepted, for example like this:

if ([[NSUserDefaults standardUserDefaults] boolForKey:@"TermsAccepted"]){
    //proceed with app normally
}
else{
//show terms
}

When accepted, the following code will change the default settings:

 if(termsaccepted){
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"TermsAccepted"];
}
NightCoder
  • 1,049
  • 14
  • 22
  • Ok thanks. Can you elaborate on just how to get the app to "proceed normally" versus "show the terms"? – jac300 Oct 14 '12 at 01:02
  • This is up to you. For example, the very first time the user launches the app, the viewController ( or the view only, if you use a single VC) displaying the terms is shown. When the terms are accepted, you close it and go to the second one as you mentioned. This can be done by the root VC as explained by alexandresoli. Next time the user comes, the root VC will show the second VC immediately. – NightCoder Oct 14 '12 at 01:16
  • Thanks. Yes, I understand the concept, but I cannot figure out the code. So let's say the terms have been accepted... how do I construct code that tells the program to "skip the current terms view and go to the next one"? In other words, in looking at alexandresoli's code piece: [self presentViewController:YOUR_TERMS_CONTROLLER animated:YES completion:nil]; what is "YOUR_TERMS_CONTROLLER", how do I label a view controller and programatically refer to it? – jac300 Oct 14 '12 at 01:26
  • 2
    Maybe this goes beyond the scope of the question. Try [this one](http://stackoverflow.com/questions/8623524/show-view-from-storyboard-chain?rq=1)or [this one](http://stackoverflow.com/questions/6231676/how-do-i-launch-a-new-view-right-after-a-purchase-is-made-and-how-can-i-make-thi?rq=1) for example. – NightCoder Oct 14 '12 at 02:02
5

Swift 3 Version

In AppDelegate.swift:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if !UserDefaults.standard.bool(forKey: "Walkthrough") {
        UserDefaults.standard.set(false, forKey: "Walkthrough")
    }
}

In root view controller:

override func viewDidLoad() {
    super.viewDidLoad()
    if UserDefaults.standard.bool(forKey: "Walkthrough") {
        // Terms have been accepted, proceed as normal            
    } else {
        // Terms have not been accepted. Show terms (perhaps using 
    }
}

When terms have been accepted, or tutorial walkthrough is finished:

UserDefaults.standard.set(true, forKey: "Walkthrough")
Jessie
  • 389
  • 4
  • 9
4

It will look like this on your first view or delegate:

NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];

BOOL isAccepted = [standardUserDefaults boolForKey:@"iHaveAcceptedTheTerms"];

if (!isAccepted) {
    [self presentViewController:YOUR_TERMS_CONTROLLER animated:YES completion:nil];
} else {
    [self.navigationController pushViewController:YOUR_NORMAL_CONTROLLER animated:YES];
}

Dont forget to save the user response on your terms controller:

[standardUserDefaults setBool:YES forKey:@"iHaveAcceptedTheTerms"];
alexandresoli
  • 918
  • 1
  • 9
  • 18
  • Ok, so I placed the first block of code in the viewDidLoad of the "terms" view controller, is that right? But then, how do I set the name of the view controller... in other words, how do I get it to recognize the name of "YOUR_TERMS_CONTROLLER"? – jac300 Oct 14 '12 at 00:30
  • YOUR_TERMS_CONTROLLER is the view controller that appear after the user accept the terms. The correct place to put the code is inside the view that calls your terms controller, it will be responsible to call the terms or not. If you have more doubts try to edit your question and put some code. – alexandresoli Oct 14 '12 at 00:34