简体   繁体   English

如何只显示一次登录屏幕?

[英]How to show login screen only once?

I'm showing the login screen when the user first opens the app. 用户首次打开应用程序时,我正在显示登录屏幕。 After the user successfully logs in, I store a session id in NSUserDefaults . 用户成功登录后,我NSUserDefaults ID存储在NSUserDefaults Then next time when the user opens the app, I check whether the session id is set. 然后,下一次用户打开应用程序时,我检查是否设置了会话ID。 If it is set then I don't want to show the login screen. 如果已设置,那么我不想显示登录屏幕。

So on first time I want to show main_controller but when user opens the app second time after successfully logging in then I want to show test_controller.rb . 所以第一次我想显示main_controller,但是当用户成功登录后第二次打开应用程序时,我想显示test_controller.rb

Question

Where should I control this flow? 我应该在哪里控制此流程?

I'm not sure how to check the session id the second time when the app opens up. 我不确定在第二次打开应用程序时如何检查会话ID。

Here is my app_delegate.rb 这是我的app_delegate.rb

class AppDelegate
  attr_reader :window

  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)

    main_controller = MainController.alloc.initWithNibName(nil, bundle: nil)
    @window.rootViewController = UINavigationController.alloc.initWithRootViewController(main_controller)

    @window.makeKeyAndVisible
    true
  end
end

main_controller.rb main_controller.rb

class MainController < UIViewController
  def viewDidLoad
    super

    self.edgesForExtendedLayout = UIRectEdgeNone

    rmq.stylesheet = MainStylesheet
    init_nav
    rmq(self.view).apply_style :root_view

    @username = rmq.append(UITextField, :username).focus.get
    @password = rmq.append(UITextField, :password).focus.get
    @sessionId = NSUserDefaults.standardUserDefaults
    puts @sessionId["sessionId"]
    if @sessionId["sessionId"] == nil
      rmq.append(UIButton, :submit_button).on(:touch) do |sender|
        puts "pressed #{@username.text} #{@password.text}"
        login_user (@username.text, @password.text)
      end
    end
  end

  def login_user(uname, pwd)
      client = AFMotion::Client.build("http://localhost:9000/") do
        header "Accept", "application/json"
        header "Content-Type", "application/json"
        request_serializer :json
        response_serializer :json
      end

      client.post("user/signup", username: uname, password: pwd) do |result|
        @sessionId["sessionId"] = result.object["sessionId"]
      end
  end

  def init_nav
    self.title = "Main"
  end
end

and finally the test_controller.rb 最后是test_controller.rb

class TestController < UIViewController

  def viewDidLoad
    super

    # Sets a top of 0 to be below the navigation control
    self.edgesForExtendedLayout = UIRectEdgeNone

    rmq.stylesheet = MainStylesheet
    init_nav
    rmq(self.view).apply_style :root_view

  end

  def init_nav
    self.title = "TEST"
  end
end

I think you can use some sort of helper class like this 我认为您可以使用类似这样的帮助程序类

AuthManager.rb AuthManager.rb

class AuthManager
  attr_accessor :sessionId

  def self.instance
    Dispatch.once { @instance ||= new}
    @instance
  end

  def init
    @keychain = KeychainItemWrapper.alloc.initWithIdentifier('EthanApp', accessGroup: nil)
    self.sessionId = @keychain.objectForKey KSecAttrAccount
  end

  def need_login?
    return (self.sessionId.nil? || self.sessionId.empty?)
  end

  def login(username, password)
    client = AFMotion::Client.build('http://localhost:9000/') do
      header 'Accept', 'application/json'
      header 'Content-Type', 'application/json'
      request_serializer :json
      response_serializer :json
    end
    client.post('user/signup', username: uname, password: pwd) do |result|
      ap result
      ap result.object
      if result.success?
        @keychain.setObject result.object[:sessionId], forKey: KSecAttrAccount
      else
        App.alert('login failed: invalid username and/or password')
      end
    end
  end

  def logout
    @keychain.setObject nil, forKey: KSecAttrAccount
  end
end

Add this to your app_delegate.rb 将此添加到您的app_delegate.rb

AuthManager.instance.init # initialize singleton object

main_controller.rb main_controller.rb

# You can control your login screen by call this method
if AuthManager.instance.need_login?
  rmq.append(UIButton, :submit_button).on(:touch) do |sender|
      AuthManager.instance.login(username, password)
  end
else
  # Display TestController
end

I would suggest that you reconsider your program flow. 我建议您重新考虑程序流程。 The case where the user is already logged in should be considered as the most common one, with the need to log in as an exception. 应将用户已经登录的情况视为最常见的一种情况,但有例外需要登录。

You can then make your test_controller the "main controller". 然后,您可以将test_controller设置为“主控制器”。 In the viewDidAppear method you can check your session details from NSUSerDefsults and display the login screen modally when required. 在viewDidAppear方法中,您可以从NSUSerDefsults检查会话详细信息,并在需要时以模态显示登录屏幕。

看一下在Xcode5加载不同的viewcontroller ...这个问题是相似的,但是出于ObjC的目的...也许您从中得到了这个主意。

Your AppDelegate is the appropriate place to put this. 您的AppDelegate是放置此控件的合适位置。 It contains various "app" events, and also controls startup flow. 它包含各种“ app”事件,并且还控制启动流程。

Like Paulw11 mentioned, your test_controller should be your main_controller, then create a "login_controller". 就像提到的Paulw11一样,您的test_controller应该是您的main_controller,然后创建一个“ login_controller”。

class AppDelegate
  attr_reader :window

  def application(application, didFinishLaunchingWithOptions:launchOptions)
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)

    if logged_in?
      create_main_controller
    else
      create_login_controller
    end

    @window.makeKeyAndVisible
    true
  end

  def logged_in?
    # Your logic here
  end

  def create_main_controller
    main_controller = MainController.new
    @window.rootViewController = UINavigationController.alloc.initWithRootViewController(main_controller)
  end

  def create_login_controller
    @window.rootViewController = LoginController.new
  end
end

When the app starts up, you check if the user is already logged in, if they are, set the rootViewController to be you main_controller, if not, set it to be the login_controller. 当应用启动时,您检查用户是否已经登录,如果已经登录,则将rootViewController设置为您的main_controller,否则将其设置为login_controller。

Once the user logs in set their info in NSUserDefaults then change the rootViewController: 用户登录后,在NSUserDefaults中设置其信息,然后更改rootViewController:

rmq.app.delegate.create_main_controller

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM