[英]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 我认为您可以使用类似这样的帮助程序类
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
AuthManager.instance.init # initialize singleton object
# 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.