我正在尝试为我的应用创建身份验证(登录)屏幕。我使用Alamofire和SwiftyJson。但是我尝试了想到的每一个解决方案来解决我的问题。
我得到的错误:尝试展示其viewController不在窗口层次结构中的viewcontroller!
问题:当我点击屏幕上的登录按钮时,我成功地从服务中获取了用户名和密码。我使用“ response.result.isSuccess”,因此我可以在此步骤之后对用户进行身份验证到下一页。这是我第一次与alamofire合作,但找不到解决方案。
发生的地方:当我从service(boolean)获得结果时,我想将用户重定向到下一页。我在下面用// ********* Error *********
标记了它我试图将请求放入控制器中,这破坏了我的MVC架构,因此我需要更好的方法来实现。我已经经历了2天的错误。
我的休息经理班;
class restManager {
var requestType: String?
var page = loginPage()
var baseURL = "myUrl" // my service url lies down here on my code
init(type: String){
self.requestType = type
}
func builder(info: userInfo){
if(requestType == "get"){
makeGetRequest(path: baseURL, info: info)
}
}
private func makeGetRequest(path: String, info : userInfo) {
let params : [String: String] = ["sUser" : nm, "sPass" : ps, "sToken": "''"]
get(parameters: params)
}
private func get(parameters: [String: String]){
Alamofire.request(baseURL, method:.get ,parameters: parameters).responseJSON { response in
print("Result: \(response.result)")
if let json = response.result.value {
print("JSON: \(json)")
self.page.auth(res: true)
}
}
}
}
还有我的loginPage视图控制器;
class loginPage: UIViewController, UITextFieldDelegate {
@IBOutlet weak var logo: UIImageView!
@IBOutlet weak var usernameTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
private var loginInfo = userInfo()
private var mng: restManager?
@IBAction func loginButton(_ sender: roundButton) {
if(usernameTextField.text != "" && passwordTextField.text != ""){
loginInfo.setUsername(info: usernameTextField.text)
loginInfo.setPassword(info: passwordTextField.text)
let mng = restManager(type: "get")
mng.builder(info: loginInfo)
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func auth(res: Bool){
if (res) {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "homePageNavCtrl") as! homePageNavCtrl
self.present(nextViewController, animated:true, completion:nil) // *********Error********
} else {
let alert = UIAlertController(title: "Error", message: "Invalid username and password.", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
我想在用户登录后显示我的导航控制器,但这不会发生。
答案 0 :(得分:1)
使用闭包/回调,因此在获得响应后,将调用成功和错误回调。这是该方法的示例。
class func alamofireRequest(URLString: String, parameters : Parameters, method:HTTPMethod, successCallback: @escaping (NSDictionary) -> Void, errorCallBack: @escaping (String) -> Void) -> Void {
Alamofire.request(URLString, method: method, parameters: parameters).responseJSON { response in
print(response)
if let JSON = response.result.value as? [String: Any] {
print(JSON)
successCallback(JSON as NSDictionary)
} else {
errorCallBack("JSON Doesn't Exist")
}
}
}
并在您的类中调用此方法,例如
let params : [String: String] = ["sUser" : nm, "sPass" : ps, "sToken": "''"]
get(parameters: params)
restManager.alamofireRequest(URLString: url,method:.get parameters: params, successCallback: { (dict) in
// Yahoo! You get the response do whatever you want
}) { (error) in
// Show error
}