Search code examples
objective-csessionnsnotification

nsnotification approach for session inactivity in objective c


In sesssion inactivity implementation for my project. I have created a NSNotification in RootViewController class of project.

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: @"Close"
                                                                             style: UIBarButtonItemStyleDone
                                                                            target: self
                                                                            action: @selector(closeModal)];

    UIImage *image = [UIImage imageNamed:@"fidelity_logotype"];
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
    [imageView setImage:image];
    [self.navigationItem setTitleView:imageView];
    self.navigationController.view.backgroundColor = [UIColor fidelityGreen];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:@"ApplicationTimeout" object:nil];
}


- (void) applicationDidTimeout:(NSNotification *) notif
{
    NSLog(@"I m here");


    BCDSessionInactivityViewController *sessionView=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"InactivityViewController"];

    sessionView.modalPresentationStyle = UIModalPresentationFormSheet;
    sessionView.preferredContentSize =  CGSizeMake(838,340);

    [[self topViewController] presentViewController:sessionView animated:YES completion:nil];

}

and in logoutviewcontroller, i am removing this observer written below

     - (IBAction)logoutbtn:(id)sender
        {
            NSLog(@"logout is called");
            [sessionTimer invalidate];


sessionTimer = nil;
        [[BCDTimeManager sharedTimerInstance]stopIdleTimer];
        //[self dismissViewControllerAnimated:YES completion:nil];

        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ApplicationTimeout" object:nil];


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


    }

This is code where i posting the notification.

- (void)idleTimerExceeded {
    NSLog(@"idle time exceeded");
    [[NSNotificationCenter defaultCenter]
     postNotificationName:@"ApplicationTimeout" object:nil];
}

for first time login, it works fine whenever timer exceeds, i post a notification and model view is presesnted perfectly, but once user logs out, after that whenever the notification is posted, selector method is getting called twice

I am pretty sure that notification is getting posted only once.

Should i create notification in every view controller and then remove it when view unloads?

what i am doing wrong here?


Solution

  • You are adding the notification in RootViewController and trying to remove it from LogoutViewController. So that notification observer added to the RootViewController never gets removed. So each time you logout and login, the observer call will get increased by one. For fixing the issue, you need to remove the observer from the RootViewController object.

    For fixing the issue you mentioned in your comment,

    If I remove the observer in RootViewController , then if timers exceeds in some other views, and notification observer is not called. Also, i can't add observer on app delegate because we want timer notification to be fired only after reaching rootviewController

    • Write two public methods in AppDelegate
      • One for adding observer (addObserver)
      • One for removing observer (removeObserver)
    • When you reach RootViewController, call the addObserver method for adding the observer
    • When logout is pressed, call the removeObserver for removing the observer