When I login to my app, my app does push the ViewController XYZMainViewController, XYZMainViewController viewWillAppear:animated call method that makes a request to my API to retrieve the authenticated user data, at this time I update the text of a label to show the user name. When I logout the app, it returns me to the login ViewController, when I do login again with another user, XYZMainViewController label text contains the name of the previous user, without updating the label text.
XYZMainViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self homeProfile];
}
- (void)homeProfile
{
[NXOAuth2Request performMethod:#"GET"
onResource:[NSURL URLWithString:#"http://{url}/users/userinfo"]
usingParameters:nil
withAccount:[XYZCommonFunctions user]
sendProgressHandler:nil
responseHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
NSDictionary *parsedData = [[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error] objectForKey:#"data"];
_user = [parsedData objectForKey:#"user"];
[self.label setText:[NSString stringWithFormat:#"Welcome %#!", [_user objectForKey:#"username"]]];
}];
}
- (IBAction)logout:(id)sender {
XYZAppDelegate* appDelegate = (XYZAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate logout];
}
XYZAppDelegate.m
- (void)login
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *identifier = [prefs stringForKey:#"accountidentifier"];
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
NSString *viewIdentifier = #"WelcomeView";
if(identifier != nil){
NXOAuth2Account *account = [[NXOAuth2AccountStore sharedStore] accountWithIdentifier:identifier];
if(account != nil) {
viewIdentifier = #"MainView";
}
UIViewController *controller = [mainStoryboard instantiateViewControllerWithIdentifier: viewIdentifier];
[navigationController pushViewController:controller animated:NO];
return;
}
}
- (void)logout
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs removeObjectForKey:#"accountidentifier"];
[prefs synchronize];
for (NXOAuth2Account *a in [[NXOAuth2AccountStore sharedStore] accounts] ){
[[NXOAuth2AccountStore sharedStore] removeAccount:a];
}
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController popToRootViewControllerAnimated:YES];
}
I need to reinitialize all data in XYZMainViewController.
Thank you.
Look like problem is related to fetching JSON Object. It is possible that everytime you have send same user to fetch user data. You are not using NSUserdefault object to display name, you are using value, which is return by JSON Object. According to me cause of error is "withAccount:[XYZCommonFunctions user]" line.
I would like to suggest, instead of using
-(void)viewWillAppear:(BOOL)animated {
you can use
- (void)viewDidLoad
so that your login action performed only when your LoginController loads,instead when LoginController appear.
New viewwillAppear look as given below -
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self.label setText:#""];
}
and ViewDidLoad -
- (void)viewDidLoad
{
[super viewDidLoad];
[self homeProfile];
}
Also check your json response, whether you are getting response success or error.According to response need to handle.
Hope this helps.
Related
i'm try to never show user login view if he logged in
i do this in viewWillAppear
-(void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"userName"]) {
NSDictionary *d = [defaults objectForKey:#"currentUser"];
UserProfile *userData = [[UserProfile alloc]initWithDictionary:d];
[[NetworkModel sharedManager] setCurrentUser:hh];
[self loginResults];
}
self.navigationController.navigationBarHidden = YES;
}
and loginResults function
-(void)childrenReceived:(NSNotification *) notification
{
[SVProgressHUD dismiss];
NSDictionary *userInfo = notification.userInfo;
NSArray *allKids = [userInfo objectForKey:#"children"];
RootViewController *sideBarRoot= [self.storyboard instantiateViewControllerWithIdentifier:#"root"];
sideBarRoot.children = allKids;
[self dismissViewControllerAnimated:YES completion:nil];
[self presentViewController:sideBarRoot animated:YES completion:nil];
}
check the below coding
#interface AppDelegate : UIResponder <UIApplicationDelegate>
-(void) didFinishLogin
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
CCKFNavDrawer*homeNavController = (CCKFNavDrawer*)[mainStoryboard instantiateViewControllerWithIdentifier:#"NavigationLoginID"];
[self.window makeKeyAndVisible];
self.window.rootViewController = homeNavController;
-(void)didFinishLogout
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UINavigationController *homeNavController = (UINavigationController*)[mainStoryboard instantiateViewControllerWithIdentifier:#"LoginNavigationID"];
LoginVC *objloginVC = (LoginVC*)[homeNavController topViewController];
objloginVC.delegate=self;
[self.window makeKeyAndVisible];
self.window.rootViewController = homeNavController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
if( [[[NSUserDefaults standardUserDefaults]objectforkey:#"loginKey"]isequaltostring:#""])
[self didFinishLogout];
else
[self didFinishLogin];
I am new to iOS. I have a UITextfield and a Keyword Search Button. When ever I want to search a keyword from a service and press enter. Tt should display the related searched keyword from a service. Please help me to fix this issue? TIA!
- (IBAction)KeywordSearchClicked:(id)sender {
NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
[self KeywordcallSignupProfileService:dict];
}
-(void)KeywordcallSignupProfileService:(NSMutableDictionary *)dict
{
[SVProgressHUD showWithStatus:#"" maskType:SVProgressHUDMaskTypeBlack]; // Progress
NSString * post = [[NSString alloc]initWithFormat:#"userId=%#&key_word%#",UserId,[dict objectForKey:#"key_word"]];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.amarbiyashaadi.com/service/amarbiya-service.svc/userKeywordSearch/"]];
RBConnect = [[RBConnection alloc]init];
RBConnect.delegate = self;
[RBConnect postRequestForUrl:url postBody:post];
}
#pragma mark - MRConnection Delegate Methods
- (void)jsonData:(NSDictionary *)jsonDict
{
[SVProgressHUD dismiss];
NSMutableArray *jsonArr;
NSMutableDictionary *userDict,*dict;
NSArray *arr=[jsonDict allKeys];
jsonArr=[jsonDict objectForKey:#"DataTable"];
if (jsonArr.count>0) {
// Save credentials in user defaults
matchesProfileArr=[jsonArr mutableCopy];
DisplayTableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"DisplayTableViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
else
{
NSString *error=#"Somthing Went Wrong";
[SVProgressHUD showErrorWithStatus:error];
}
}
I am pretty stuck with this and hoping someone can show me some light about this.
I need help to figure out how to refresh the table list on the main view from the slide-in menu.
IN MAIN VIEW
So basically, I have a main view that has a list of events. I use this function to retrieve data from the database:
[self loadEvents:eventCat sortEvent:nil searchDate:dateSelected];
Inside that function, it has the script that gets data, determines if there is content and then reloads the table:
- (void)loadEvents:(NSString*)searchType sortEvent:(NSString*)sortType searchDate:(NSString *)dateSelect{
NSString *url = [NSString stringWithFormat: #"http://www.url.com/eventList.php];
NSURL *eventURL = [NSURL URLWithString: url];
NSLog(#"%#", eventURL);
NSData *jsonData = [NSData dataWithContentsOfURL: eventURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error: &error];
self.eventList = [NSMutableArray array];
NSArray *eventArray = [dataDictionary objectForKey:#"fitpass"];
//NSString *eventFound = [dataDictionary objectForKey:#"notfound"];
//if nothing is found
if ([dataDictionary objectForKey:#"notfound"]){
tableView.hidden = YES;
noEvent.hidden = NO;
NSLog(#"123");
}else{
noEvent.hidden = YES;
tableView.hidden = NO;
NSLog(#"RELOADDATA");
for(NSDictionary *eventDictionary in eventArray){
Event *event = [Event blogPostWithTitle:[eventDictionary objectForKey:#"name"]];
event.eventTime = [eventDictionary objectForKey:#"event_time"];
[self.eventList addObject:event];
[tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
}
I tried using the NSNotificationCenter method to refresh the data. So I have this in the viewDidLoad Method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refreshTableWithNotification:) name:#"RefreshTable" object:nil];
Then this function right after ViewDidLoad Method:
- (void)refreshTableWithNotification:(NSNotification *)notification
{
[self.tableView reloadData];
}
IN THE SLIDE MENU VIEW
In the side menu, I have a table list to populate the different categories, and when use click a category, it should refresh the event list in the main view:
//on direct press, trigger segue
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//get current value and set the eventCategory ID in userDefault
NSDictionary *catPicked = [self.catList objectAtIndex:indexPath.row];
NSString *eventCat =[catPicked objectForKey:#"ID"];
NSLog(#"%#Picked:", eventCat);
[userDefaults setObject:eventCat forKey:kEventCat];
[userDefaults synchronize];
NSLog(#"%#entered", [userDefaults objectForKey:kEventCat]);
//redirect back to eventList;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier: #"eventListViewController"];
//refresh data
EventLists *destinationController = [[EventLists alloc] init];
[destinationController loadEvents:eventCat sortEvent:nil searchDate:nil];
//send notofication over
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshTable" object:nil userInfo:nil];
[destinationController.view setNeedsDisplay];
[[SlideNavigationController sharedInstance] popToRootAndSwitchToViewController:vc
withSlideOutAnimation:self.slideOutAnimationEnabled
andCompletion:nil];
return;
}
What I am stuck is that I can see the data (eventList) is updated, but the view does not refresh...
Any help would be very much appreciated!!!
Rory!!!
Thank you so much for your help!! I finally figured it out with your hint.
So basically I thought it was passing he data because of my log. But it was just merely running the function. No data was passed.
And the solution was actually rather simple. Since the data was not really being passed over, refreshing the table in the notification function will not work. The data needs to be reloaded. In other word, I just needed to change the notification function in the Main View to:
- (void)refreshTableWithNotification:(NSNotification *)notification
{
[self loadEvents:[userDefaults objectForKey:kEventCat] sortEvent:nil searchDate:dateSelected];
}
Then my Side Menu View is now much simpler since all I needed was the Notification call and view switch:
//redirect back to eventList;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier: #"eventListViewController"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshTable" object:nil userInfo:nil];
And yes! I needed to move the notification in the Main view to ViewDidAppear:
- (void)viewDidAppear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refreshTableWithNotification:) name:#"RefreshTable" object:nil];
}
Thank you so much for your help!!
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"username"] == nil)
{
//Load Login View if no username is found
NSLog(#"No username found");
self.nameLoginView=[[NewLoginViewController alloc]initWithNibName:#"NewLoginViewController" bundle:nil];
[self.navigationController pushViewController:self.nameLoginView animated:YES];
}
else
{
NSString *savedUsername = [defaults stringForKey:#"username"];
NSLog(#"Username found: %#", savedUsername);
self.mainView = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[self.navigationController pushViewController:self.mainView animated:YES];
}
I mean if he is logging for first time in our app he has to go to newLoginView Controller and if user is logging for second time he has to go to another view controller? i am doing this code in view controller itself?
Hope i am getting right your problem, you have problem to find that user is saved in your user Default or new user please have a look of below link:Click here to find solution
Hope this will be help full for you.
NSString *userName = [[NSString alloc] init];
NSString *userPass = [[NSString alloc] init];
userName = [[NSUserDefaults standardUserDefaults] objectForKey:#"username"];
userPass = [[NSUserDefaults standardUserDefaults] objectForKey:#"password"];
if([userName isEqualToString:name.text] && [userPass isEqualToString:passcode.text])
{
authgrantflag=1;
}
// Compare entered combo with configurator stored values ---Offline Authentication //
NSLog(#"Authentication flag=%d",authgrantflag);
if(authgrantflag==1)
{
// Local authentication successfull call home page//
NSLog(#"Local authentication success");
[pop1 dismissPopoverAnimated:YES];
HomeScreen *dcrmainpage=[[[HomeScreen alloc] initWithNibName:nil bundle:nil]autorelease];
[self presentViewController:dcrmainpage animated:YES completion:nil];
}
else
{
HomeScreen1 *dcrmainpage=[[[HomeScreen1 alloc] initWithNibName:nil bundle:nil]autorelease];
[self presentViewController:dcrmainpage animated:YES completion:nil];
}
The scenario is when the app first loads (controller A loads), it checks if an NSDefaultuser exist. If it does not exist then it sends it to (Controller B). In controller B the user enters his/her username then clicks ok. Now, NSDefault is saving the username and it should also redirect it back to the main view controller. Here is the code:
if([Username.text isEqual: #""]) {
[self showOkAlert:#"Username required"];
}
else if([Password.text isEqual:#""]) {
[self showOkAlert:#"Password required"];
}
else {
//suppose that login was successfully.
[self SaveCredentials];
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"LatestNews"];
[self presentViewController:vc animated:YES completion:nil];
}
Controller A:
- (void)LoadCredentials {
//load username
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults objectForKey:#"User"];
if(!username) {
[self showAlert:#"user does not exist"];
[self dismissViewControllerAnimated:YES completion:nil];
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"Login"];
[self presentViewController:vc animated:YES completion:nil];
}else{
[self showAlert:#"user exists"];
// for testing purposes I want it to reset when user logged in. Just so I know it resets. Later this method will be called from logout button.
[self resetUsernameWhenLogout];
}
}
-(void)resetUsernameWhenLogout {
//reset username when logout
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)viewDidLoad
{
[self LoadCredentials];
}
There are a couple of possibilities here; Firstly, iOS8 seems to instantiate the VC's a lot earlier than in iOS7, so the Navigation tree isn't complete in viewDidLoad, You should only use viewDidLoad for additonal initialization. Try moving your code [self LoadCredentials];
} to viewWillAppear.
Secondly, if you have a nav controller, you should be adding the new VC to the nav tree via the nav controller. If this is the case, try the code below.
if([Username.text isEqual: #""]) {
[self showOkAlert:#"Username required"];
}
else if([Password.text isEqual:#""]) {
[self showOkAlert:#"Password required"];
}
else {
//suppose that login was successfully.
[self SaveCredentials];
//This does not work - I receive a thread error not sure how to debug it
UIStoryboard *storyBoard = self.storyboard;
UIViewController *targetViewController = [storyBoard instantiateViewControllerWithIdentifier:#"LatestNews"];
UINavigationController *navController = self.navigationController;
if (navController) {
[navController pushViewController:targetViewController animated:YES];
}
}