2

My App contains a couple of views, I would like to display a small setup when the app launches and the user didn't complete the wizard yet. I know I can achieve this with NSUserDefaults, But I'm unsure how I can make it to display a specific view depending on the input string of the NSUserDefaults storage.

My AppDelegate.m:

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

    NSString *controllerName = [[NSUserDefaults standardUserDefaults] objectForKey:@"WIZARD_VIEW"];
    if ([controllerName length]) {
        Class controllerClass = NSClassFromString(controllerName);
        UIViewController *controller = [[controllerClass alloc] init];

    // Override point for customization after application launch.
    return YES;
    }

Then in the viewcontroller files I added the following code as suggestion from jfaller:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSUserDefaults* standard=[NSUserDefaults standardUserDefaults];
    [standard registerDefaults: @{ @"WIZARD_VIEW" : [[self class]description]} ];    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSUserDefaults* standard=[NSUserDefaults standardUserDefaults];
    [standard registerDefaults: @{ @"WIZARD_VIEW" : [[self class]description]} ];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

But how can I make this so it will display the specific view that has been selected in the setup?

user1839995
  • 113
  • 2
  • 9
  • You don't want to call registerDefaults: here. You generally only call registerDefaults once per application boot. You truly do want to call setObject:forKey:. – jfaller Nov 21 '12 at 15:14

2 Answers2

3

Personally, I would do the following:

Every time a user goes to a new view in your wizard, record the UIViewController in the user defaults:

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [[NSUserDefaults standardUserDefaults] setObject:[[self class] description] forKey:WIZARD_VIEW];
  [[NSUserDefault standardUserDefaults] synchronize];
}

- (void)viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  [[NSUserDefaults standardUserDefaults] removeObjectForKey:WIZARD_VIEW];
  [[NSUserDefault standardUserDefaults] synchronize];
}

When the user restarts the app (hypothetically in the middle of the wizard), reload the view:

- (BOOL)application:(UIApplication *)application
    willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // etc.
  NSString *controllerName = [[NSUserDefaults standardUserDefaults] objectForKey:WIZARD_VIEW];
  if ([controllerName length]) {
    Class controllerClass = NSClassFromString(controllerName); 
    NSViewController *controller = [[controllerClass alloc] init];
    // push the controller, or whatever....
  }
  // etc.
}
jfaller
  • 508
  • 2
  • 6
  • Before I accept this as answer (because it almost did the job) could you please make the "willFinishLaunchingWithOptions" more clear since it's really bugged according to xcode, thanks in advance for the great help! – user1839995 Nov 20 '12 at 20:57
  • To be more specific, I'm using ARC and it gives the following errors: "Implict conversion from int to class is disallowed with ARC" - "objc_lookUpClass is invalid in C99" and a couple more.. – user1839995 Nov 20 '12 at 21:02
  • try: Class controllerClass = NSClassFromString(controllerName); It doesn't require a header and a few other things ARC complains about. – jfaller Nov 20 '12 at 21:02
  • Using the fixed code my whole App won't start anymore. Please take a look at my first updated post, thanks in advance. – user1839995 Nov 21 '12 at 07:32
  • It's a little hard to understand, "my app won't start anymore." Any other hints there? :) Other than that, you have to actually do something with the UIViewController you create with the alloc/init. For example, if you have a UINavigationController app, you need to push the view controller, etc. – jfaller Nov 21 '12 at 14:42
  • Ah, so that was the problem. I fixed my code again showed in the first post. I always use story boards so I'm unsure how I should code the controller to do something I can't use CTRL to add the code. Any ideas? – user1839995 Nov 21 '12 at 14:50
  • If you're using storyboards, I think your problem is easier. You can just save the tab index of the latest tab the users navigated to, and then when the user starts the app you send them back to that tab. I don't know storyboards real well -- having only played with them for a short period of time. I'm sure that if you google around for tab index, and navigating to a tab, you should find the answer you're looking for. – jfaller Nov 21 '12 at 15:05
  • I'm not using a tab view, I'm using a root navigation controller with views, I want to use the method you explained above since it seems the solution for my problem. – user1839995 Nov 21 '12 at 15:14
  • This has what you're looking for: http://stackoverflow.com/questions/7889510/ios-5-storyboard-programmatically-determine-path – jfaller Nov 21 '12 at 15:21
  • Sorry, I totally don't understand that. I don't know what they are trying to do there since I'm a beginner in xcode. – user1839995 Nov 21 '12 at 15:29
  • This is better handled in chat, or with another question. If I were you, submit a question asking, "I know which view in a storyboard I want to go to, but I don't know how." Explain your problem, etc. :) – jfaller Nov 21 '12 at 19:53
1

Write the view you are on to NSUserDefaults as the view loads. Then check for the value in didFinishLaunchingWithOptions.

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

    if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"current_setup"] isEqualToString:@"1"]) {

         //on view 1!   

    }

}
Jack Humphries
  • 13,056
  • 14
  • 84
  • 125