它说:
尝试出示< UIAlertController:0x106155a00> on< SignInViewController:0x105f490a0>其视图不在窗口层次结构中!
@IBAction func signIn(_ sender: Any) {
if let emailField = email.text, let passField = password.text {
Auth.auth().signIn(withEmail: emailField, password: passField, completion: { (user, error) in
if error != nil {
guard let error = AuthErrorCode(rawValue: (error?._code)!) else {
return
}
self.fireErrorHandle(code: error)
}else{
if let userID = user?.uid {
KeychainWrapper.standard.set((userID), forKey: "uid")
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
})
}
}
func fireErrorHandle(code: AuthErrorCode) {
switch code {
case .invalidCustomToken:
//print("Indicates a validation error with the custom token")
showAlert(title: "Error", message: "Validation error with the custom token.")
case .customTokenMismatch:
//print("Indicates the service account and the API key belong to different projects")
showAlert(title: "Error", message: "Id Mismatch.")
case .invalidCredential:
//print("Indicates the IDP token or requestUri is invalid")
showAlert(title: "Error", message: "RequestUri is invalid.")
case .userDisabled:
//print("Indicates the user's account is disabled on the server")
showAlert(title: "Error", message: "Account is disabled.")
case .operationNotAllowed:
//print("Indicates the administrator disabled sign in with the specified identity provider")
showAlert(title: "Error", message: "Administrator disabled sign in.")
case .emailAlreadyInUse:
//print("Indicates the email used to attempt a sign up is already in use.")
showAlert(title: "Error", message: "Email already in use.")
case .invalidEmail:
//print("Indicates the email is invalid")
showAlert(title: "Error", message: "Email is invalid.")
case .wrongPassword:
//print("Indicates the user attempted sign in with a wrong password")
showAlert(title: "Error", message: "Wrong password.")
case .tooManyRequests:
//print("Indicates that too many requests were made to a server method")
showAlert(title: "Error", message: "To many requests were made please try again late.")
case .userNotFound:
//print("Indicates the user account was not found")
showAlert(title: "Error", message: "Account was not found.")
case .accountExistsWithDifferentCredential:
//print("Indicates account linking is required")
showAlert(title: "Error", message: "account linking is required.")
case .requiresRecentLogin:
//print("Indicates the user has attemped to change email or password more than 5 minutes after signing in")
showAlert(title: "Error", message: "Attemped to change email or password more than 5 minutes after signing in.")
case .providerAlreadyLinked:
//print("Indicates an attempt to link a provider to which the account is already linked")
showAlert(title: "Error", message: "Link a provider to which the account is already linked.")
case .noSuchProvider:
//print("Indicates an attempt to unlink a provider that is not linked")
showAlert(title: "Error", message: "Attempt to unlink a provider that is not linked.")
case .invalidUserToken:
//print("Indicates user's saved auth credential is invalid, the user needs to sign in again")
showAlert(title: "Error", message: "Please sign in again.")
case .networkError:
//print("Indicates a network error occurred (such as a timeout, interrupted connection, or unreachable host). These types of errors are often recoverable with a retry. The @cNSUnderlyingError field in the @c NSError.userInfo dictionary will contain the error encountered")
showAlert(title: "Error", message: "You have been timesout due to network error. Please try again.")
case .userTokenExpired:
//print("Indicates the saved token has expired, for example, the user may have changed account password on another device. The user needs to sign in again on the device that made this request")
showAlert(title: "Error", message: "May have changed account password on another device.")
case .invalidAPIKey:
//print("Indicates an invalid API key was supplied in the request")
showAlert(title: "Error", message: "error")
case .userMismatch:
//print("Indicates that an attempt was made to reauthenticate with a user which is not the current user")
showAlert(title: "Error", message: "Error logging in.")
case .credentialAlreadyInUse:
//print("Indicates an attempt to link with a credential that has already been linked with a different Firebase account")
showAlert(title: "Error", message: "Credential that has already been linked with a different account.")
case .weakPassword:
//print("Indicates an attempt to set a password that is considered too weak")
showAlert(title: "Error", message: "Password to weak.")
case .appNotAuthorized:
//print("Indicates the App is not authorized to use Firebase Authentication with the provided API Key")
showAlert(title: "Error", message: "Not authorized")
case .keychainError:
//print("Indicates an error occurred while attempting to access the keychain")
showAlert(title: "Error", message: "An error has occured please try again")
default:
//print("Indicates an internal error occurred")
showAlert(title: "Error", message: "Internal error, please try again.")
}
}
func showAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message:message, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if Auth.auth().currentUser != nil {
Timer.scheduledTimer(withTimeInterval: 0, repeats: false, block: { (timer) in
self.performSegue(withIdentifier: "toFeed", sender: nil)
})
}
if KeychainWrapper.standard.object(forKey: "uid") != nil {
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
signInbutton.isEnabled = false
}
我尝试了很多不同的解决方案,无法弄清楚要做什么,我尝试将其添加到viewdidappear但我不知道如何将AuthErrorCode添加到它。当我按下登录按钮时,它会执行到另一个视图控制器的segue,而不会进行任何错误处理。
答案 0 :(得分:2)
你可以试试这个:
private func presentViewController(alert: UIAlertController, animated flag: Bool, completion: (() -> Void)?) -> Void {
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: flag, completion: completion)
}
您应该注意的其他事项是您是否正确设置了rootViewController,因为这可能是导致此错误的原因。
答案 1 :(得分:0)
确保SignInViewController尚未呈现您将要呈现UIAlertController的控制器,因为您无法在已呈现的UIViewController上呈现UIAlertController。
如果这样做,您将收到以下错误。
尝试出席 谁的观点不在窗口 层次!