【问题标题】:What is the perfect way to make a logout from IOS app?从 IOS 应用程序注销的完美方法是什么?
【发布时间】:2013-01-15 23:07:55
【问题描述】:

下面的代码可以运行,但有一个错误。场景是,我首先登录进入应用系统。登录成功后,应用程序将设置 UserDefaults (UserId)。之后,我可以使用存储的 UserId 导航应用程序视图。一旦我进入设置和选项卡注销,这将清除 UserId 并进入登录视图。

BUG:当我再次登录应用程序并单击主页按钮转到iPhone桌面并关闭应用程序,然后返回再次打开它仍然存储用户ID。因此,如果我进入设置并注销,这将清除 UserId 并且不会进入登录视图。我不知道为什么。

代码:

- (IBAction)resetKeychain:(id)sender {

    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                 initWithTitle:@"Are you sure you want to logout?" 
                 delegate:self 
                 cancelButtonTitle:@"Cancel" 
                 destructiveButtonTitle:@"Logout"
                 otherButtonTitles:nil];
    actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
    [actionSheet showFromTabBar:self.tabBarController.tabBar];
    [actionSheet release];

}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex ==0) {
        //logout
        NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
        //delete user ID fro user Defaults
        [defaults setObject:nil forKey:@"UserId"];
        //redirect to login view

        NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
        [appsDelegate.window addSubview:[appsDelegate.login view]];

    }
}

【问题讨论】:

  • 没有所谓的“完美解决方案”。请记住,最好的人是善的敌人。

标签: iphone ios logout


【解决方案1】:

制作UINavigation控制器的属性并合成,并在注销按钮上写下代码

AppDelegate * appDelegateObj =[[UIApplication sharedApplication] delegate];
    login *loginObj = [[login alloc]initWithNibName:@"login" bundle:nil];
    [appDelegateObj.window setRootViewController:nil];
    navObj=[[UINavigationController alloc]initWithRootViewController:loginObj];
    [appDelegateObj.window setRootViewController:navObj];

【讨论】:

  • 为什么需要UINavigationController? OP 不在导航堆栈中显示登录控制器。除此之外,我没有看到已经发布的其他答案的任何补充。
【解决方案2】:

从我可以从你的问题中解释出来,顺便说一下,这个问题需要格式化和连贯,我相信:

a) 您的 @"UserID" 值未与 NSUserDefaults 同步,因为您没有调用 -synchronize 方法。 NSUserDefaults 将更新其内存键值存储,但不会将其写入磁盘,这意味着它会在任意时间丢失。

b) 它不会转到loginView 的事实可能与任何几个原因有关,很可能它已经是您的UIWindow 的子视图。因此,不要在您的应用委托中重用 login 属性,而是创建 View Controller 的新实例变量,并将其设置为 rootViewController

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex == 0) {
        NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject:nil forKey:@"UserId"];
        [defaults synchronize];
        //redirect to login view

        NewClassMoonAppDelegate * appsDelegate =[[UIApplication sharedApplication] delegate];
        LoginViewController *login = [[LoginViewController alloc] initWithNibName...];
        [appsDelegate.window setRootViewController:nil];
        [appsDelegate.window setRootViewController:login];

    }
}

【讨论】:

  • 嘿 max_,您的解决方案很棒,但我确实有疑问,我是否需要在登录应用程序之前从我加载的内存中删除所有其他 MVC?如果不是这些 MVC 会发生什么?他们会在记忆中吗?这种情况应该如何处理?
  • rootViewController 和 rootViewController 本身呈现的任何内容都将从内存中释放。这不会立即生效,因为您可能会在应用程序的其他地方保留引用,或者编译器可能还没有准备好这样做。
【解决方案3】:

斯威夫特

来自 max_ 的回答有一些变化:

let objectsToSave: [String] = [obj1, obj2, obj3]
for key in objectsToSave {
    NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
}

 let appsDelegate = UIApplication.sharedApplication().delegate
 let storyboard = UIStoryboard(name: "MainStoryboard", bundle: nil)
 let newLoginVC: LoginViewController = storyboard.instantiateInitialViewController() as! LoginViewController
 appsDelegate?.window!!.rootViewController = nil
 appsDelegate?.window!!.rootViewController = newLoginVC

编辑:我所做的唯一更改是我通过情节提要初始化 newLoginVC 而不是 initWitName

【讨论】:

  • 请再解释一下,为什么要进行更改以及您通过它取得的成果。
  • 这个解决方案可以导航回 loginVC,但是,当注销发生时,已分配给前一个用户会话的视图控制器不会被释放。我们如何释放所有视图控制器?
猜你喜欢
  • 2016-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-19
  • 2013-12-11
  • 2019-09-20
  • 2015-02-26
相关资源
最近更新 更多