0

I am working over a simple application for iOS in Xcode 5.1.1. I am a newbie in Xcode and Objective-C, so I have a little problem. This is what I have: enter image description here

Idea of my application is very simple - when user launch application first time, he see Authorization form. When he enter his Login and Password and press Sign In, my application make request to server, and if everything is ok - login and password are correct - application save user login:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject:self.txtUsername.text forKey:@"SavedUserName"];
        [defaults synchronize];

and opens view with "It's Ok!".

[self performSegueWithIdentifier:@"login_success" sender:self];

Authorization is work great, user login saving os works to. But now, when user launch app again I need to open view with "It's OK", if he already authorized:

- (void)viewDidLoad
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *authLogin = [defaults objectForKey:@"SavedUserName"];
    if(![authLogin isEqualToString:@""]){
         //I think here application must load view with "It's OK!", but how to do this?
         //I tried to use here this - [self performSegueWithIdentifier:@"login_success" sender:self]; but it doesn't works.
    }
}

Please, help me, how to solve my problem? P.S. I try to find answer on my question in Google and here on StackOverflow, but all that I find and try to use didn't help me.

Community
  • 1
  • 1
Evgeny
  • 95
  • 6
  • I think you should try to use the AppDelegate : `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` and do some checking in there. Because I see that you are doing your _already authorized_ check in a `- (void)viewDidLoad` which is in a ViewController. So I guess you are always opening the _Authorization_ view and if you are authorized, you go to the _OK_ view?! – ySiggen Apr 22 '14 at 11:43
  • yes, you are right! hmm.. where I should place `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`? – Evgeny Apr 22 '14 at 11:54
  • I found it in AppDelegate.m. Thats it?) – Evgeny Apr 22 '14 at 11:56
  • Yes, it is there and it is easier (when you start developing in iOS) to use this in order check if something is already done (like if you are already authenticated), simply because it will stay _alive_ for the duration of your app. Which is not the case for View Controllers (if you move to another view, another View Controller is called). Using a BOOL like @NKB suggested and checking it (if you are logged in or not) in your AppDelegate (and then open the corresponding view from there) might be the easiest way (to begin)! – ySiggen Apr 22 '14 at 12:28

4 Answers4

0

Keep a flag, or store a bool value in NSUserDefaults. This way you can track if the user is already authorized you can show the second view else you could load login form.

NKB
  • 651
  • 5
  • 13
  • hmm) but my problem is how to show second view if user already authorized?) – Evgeny Apr 22 '14 at 11:52
  • So is it like if the user is already authorized you want your application to start with second VC ? – NKB Apr 22 '14 at 11:57
  • Then you should check in the appdelegate the flag value and correspondingly set the root view controller or initial view controller.. – NKB Apr 22 '14 at 12:00
  • @Evgeny I think the last comment of NKB would be just what you need. Some code could be welcome here! – ySiggen Apr 22 '14 at 12:38
0

My application also handles some authorization flow (PIN-Registration). I work with two storyboards. One for the Registration/Login Progress (Login.storyboard) and one when the user is connected to the service.

The following code is under application:didFinishLaunchingWithOptions: after some initializations:

// Set rootview (Check if user is registred)
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

if ([ccmpService isRegistered]) {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    self.window.rootViewController = [storyboard instantiateInitialViewController];

    if (launchOptions) {
        NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        [self handleRemoteNotifications:remoteNotif];
    }
} else {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil];
    self.window.rootViewController = [storyboard instantiateInitialViewController];
}

[self.window makeKeyAndVisible];
return YES;



When i want to change the storyboards (Login / Logout) i call something like (also declared in the App Delegate:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *sourcetVC = self.window.rootViewController;
UIViewController *destVC = [storyboard instantiateInitialViewController];

[UIView transitionFromView: sourcetVC.view
                    toView: destVC.view
                  duration: 0.5
                   options: UIViewAnimationOptionTransitionFlipFromRight
                completion: ^(BOOL finished) {
                    self.window.rootViewController = destVC;
                }];
0

Instead of having:

- (void)viewDidLoad { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *authLogin = [defaults objectForKey:@"SavedUserName"]; if(![authLogin isEqualToString:@""]){ ... } }

I would put:

- (void)viewWillAppear
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *authLogin = [defaults objectForKey:@"SavedUserName"];
    if(![authLogin isEqualToString:@""]){
         // programmatically invoke a push segue to the next view controller
         [self performSegueWithIdentifier:"pushToMyVC" sender:self];
    }
}

Be sure to give the segue a storyboard id in Interface Builder. For other options, check out this thread.

Don't quote me on this, but I believe viewWillAppear gets called every time the view is about to be displayed. So if you are navigating back and forth to this view, you'll want to make sure the user is logged in.

Community
  • 1
  • 1
Sam
  • 687
  • 7
  • 18
0

Just set the second VC (not the login VC) as the initial scene and then use delegation. Something like this:

In your LoginVC:

@protocol LoginViewControllerDelegate
    -(void)finishedLoggingInUser:(NSString *)userName;
@end


@interface LoginViewController : UIViewController {
    __unsafe_unretained id <LoginViewControllerDelegate> _delegate;
}

@property (nonatomic, assign) id <LoginViewControllerDelegate> delegate;

Then in the implementation of the LoginVC, fire off the delegate method after logging them in:

[_delegate finishedLoadingUserInfo:@"MyUsername"];

Then in the initial VC, declare yourself as a delegate for the LoginViewController:

#import "LoginViewController.h"

@interface MyInitialViewController : UIViewController <LoginViewControllerDelegate> 

And implement the delegate method in the implementation:

#pragma mark - LoginViewController Delegate Method
-(void)finishedLoggingInUser:(NSString *)userName {
    // Do something with the user info
    self.loggedInUserName = userName;

    [self dismissViewControllerAnimated:YES completion:nil];
}
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62