在 App Delegate 上调用服务器后如何更改根控制器?

Posted

技术标签:

【中文标题】在 App Delegate 上调用服务器后如何更改根控制器?【英文标题】:How to change root controller after a server call on App Delegate? 【发布时间】:2016-03-05 13:44:17 【问题描述】:

我正在尝试更改应用委托上的根控制器。

我正在调用服务器以检查登录会话是否有效。如果有效,则显示欢迎页面,否则显示登录页面。

在 appDelegate 中,我在方法 didFinishLaunchingWithOptions 中进行服务器调用。

我通过我的数据模型委托获得响应,但是当我从服务器获得响应时,旧的根控制器已经出现在屏幕上。

目前,旧的根控制器首先出现,在几分之一秒内,新的根控制器就出现了!所以它看起来像一个闪烁的东西!

有没有办法让旧的根控制器一直显示,直到我从服务器获得响应?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    // Override point for customization after application launch.

    _dataModel=[DataModal sharedInstance];
    _dataModel.delegate=self;

    NSString *token=[[NSUserDefaults standardUserDefaults]objectForKey:@"token"];
    if (!token) 
        token=@"jkfhgjkfg908";
    else
         _dataModel.auth_token=token;
    

    [_dataModel checkToken:token];

    return YES;


//By the time it reaches here, the old root controller is already present on screen
-(void)checkToken:(NSDictionary *)items

    if ([items[@"success"] isEqual:@1]) 
        AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
        UIStoryboard *storyboard=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
        app.window.rootViewController=[storyboard instantiateViewControllerWithIdentifier:@"DashboardNavController"];

    else
        //do nothing, defualt is login view
    


【问题讨论】:

为什么不在登录视图中移动代码检查用户会话? 我没有偏好,但如果这种方式不起作用,我会这样做。我想知道是否有办法在应用委托上做到这一点! 现在回头看这个问题,我不记得上下文了lol 【参考方案1】:

您不应该等待服务器调用来决定您的根视图控制器 - 一旦didFinishLaunchingWithOptions 被调用,您需要呈现一个视图。

Root View Controller 在加载时呈现一个初始视图控制器并坚持使用它 - 它是根是有原因的。

如果您缓存了令牌,请跳过您的 loginViewController 并继续。计划没有互联网/不良连接/过期令牌,但不要在应用程序委托中放置异步操作,以防止您的 UI 被呈现。

【讨论】:

这是有道理的!我将尝试修复一个根控制器!【参考方案2】:
    取消选中Is initial View ControllerMain.storyboard 中控制器的复选框 初始化appDelegate的window属性:appDelegate.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 设置rootViewController:appDelegate.window.rootViewController = controller; 并调用makeKeyAndVisible方法:[appDelegate.window makeKeyAndVisible];

【讨论】:

如果我取消选中初始视图控制器,它会完全黑色一段时间,并且在出现黑色窗口后加载新的根控制器!!!如果我没有发现任何有用的东西,我将采用这种方式!谢谢!【参考方案3】:

在我看来,使用initialViewController作为入口,而不是改变rootViewController,是一种更好的方法。当应用程序启动时,必须有一个屏幕让用户感觉一切顺利。此外,您正在向服务器发出请求,此过程可能会失败或超时。

我的建议是通过 initialViewController 进行导航。使其可见并放置一些动画或活动指示器,然后当响应到来时,如果已登录,则转到您的应用程序 mainViewController,否则转到 loginViewController。您也可以在这里检查互联网连接并建议用户连接到互联网。

【讨论】:

你是对的,所以在这种情况下,旧的原生启动 screen.xib 不会有太大帮助!!!【参考方案4】:

您不能让旧的视图控制器呈现,但您可以呈现一个黑屏的视图控制器,然后在您收到服务器关于会话的响应后,您可以根据您的需要呈现视图控制器。

【讨论】:

以上是关于在 App Delegate 上调用服务器后如何更改根控制器?的主要内容,如果未能解决你的问题,请参考以下文章

可以在 App Delegate 中调用 Web 服务吗?

从 App Delegate 打开导航控制器

从 App Delegate 调用 ViewController 的方法

App Delegate 的应用程序:didReceiveLocalNotification:未调用

在另一个类的 App Delegate 调用方法中

从 App Delegate 调用时,PushViewController 不起作用