I have a helper method that prompts an alertviewcontroller on my actual view controller. however, if this happens during a segue. my segue gets cancelled. Any ideas?
AlamoHelper.request(.POST, url: AppDelegate.kbaseUrl + "users/signin", parameters: ["email": String(emailTextField.text!), "password": String(passwordTextField.text!)])
.responseJSON {
response in
switch (response.result) {
case .Success:
var json = JSON(response.result.value!)
if (json["status"] != 200){
AppDelegate.removeCookies()
AppDelegate.isLoggedIn = false
} else {
self.performSegueWithIdentifier("showTabBarController", sender: self)
self.emailTextField.text = ""
self.passwordTextField.text = ""
self.appDelegate.storeCookies()
AppDelegate.isLoggedIn = true
self.addDeviceToken()
}
break
case .Failure:
break
}
}
in my helper, the part where I show the alert controller is this
if json["status"].intValue == 500 {
let alert = UIAlertController(title: "Unknown error", message: "Please try again later. If problem persists, please contact Offpeak support", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Cancel, handler: nil)
alert.addAction(okAction)
AlamoHelper.getCurrentViewController().presentViewController(alert, animated: true, completion: nil)
}
Related
I have a problem trying to put an alert message after completing the action. The application crashes.
#IBAction func deleteAccountAction(_ sender: Any) {
let userID = prefs.value(forKey: "userId") as! String
print("user id: \(userID)")
let alert = UIAlertController(title: "Delete account", message: "Are you sure you want to delete your account?, This action cannot be reversed.", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
// ...
}
let okayAction = UIAlertAction(title: "OK", style: .default) { (action) in
RestAPIManager.sharedInstance.deleteAccount(userID: userID){
(json, error) in
if(json != JSON.null){
print(json)
if(json["success"] == true){
//here i want succes alert
}else{
self.errorAlert()
}
}else{
}
}
}
alert.addAction(okayAction)
alert.addAction(cancelAction)
self.present(alert, animated: true)
}
func errorAlert(){
var dialogMessage = UIAlertController(title: "Error", message: "Error", preferredStyle: .alert)
self.present(dialogMessage, animated: true, completion: nil)
}
I tried to put an alert message after the action but I can't.
is solved needs to be async.
DispatchQueue.main.async {
self.errorAlert()
}
When I save data under userID the data is not being stored into the Firebase and give error unexpectedly found nil while unwrapping an optional value, however when I use childByAutoID the data is being stored successfully. Help me to save under userID node. Here I have explained that when I create the user under signup action this is happening.
#IBAction func createAccountAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
let alertController = UIAlertController(title: "Error", message: "Please enter your email and password", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else if (self.passwordTextField.text != self.retypePasswordfield.text) {
let alertController = UIAlertController(title: "Error", message: "Password does not match", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
present(alertController, animated: true, completion: nil)
} else {
ref.child("user_registration").setValue(["username": self.fullName.text, "email": self.emailTextField.text,"contact": self.numberText.text, "city": self.myCity.text, "state": self.countryText.text, "gender": genderGroup, "blood": bloodGroup])
FIRAuth.auth()?.createUser(withEmail: emailTextField.text!, password: passwordTextField.text!) { (user, error) in
if error == nil {
FIRAuth.auth()?.currentUser!.sendEmailVerification(completion: { (error) in
})
print("You have successfully signed up")
let alertController = UIAlertController(title: "Successful!", message: "Email Verification link sent", preferredStyle: .alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .default) { (action) in
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginFirstViewController")
self.present(vc!, animated: true, completion: nil)
}
alertController.addAction(alertActionOkay)
self.present(alertController, animated: true, completion: nil)
} else {
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
Only for reference
This is the current working code for me
On signUp Button
// Create new User
FIRAuth.auth()?.createUser(withEmail: self.tfEmail.text!, password: self.tfPassword.text!, completion: { (user, error) in
if error == nil{ // IF NO ERROR
let astrContact = self.strDialCode + " " + self.tfMobileNumber.text!
// Dict to add user data in firebase Db
let aDBDict : [String : String] = ["userName": self.tfFullName.text!,
"userEmail": self.tfEmail.text!,
"userContact": astrContact,
"userCountry": self.strCode,
"userID": (user?.uid)!]
// Add data in DB
ref?.child("Customer/\(String(describing: (user?.uid)!)/userProfileDetails").setValue(aDBDict)
DispatchQueue.main.async(execute: { () -> Void in
// goto home VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyboard.instantiateViewController(withIdentifier: "MainController")
if let window = AppDelegate.getAppDelegate().window {
window.rootViewController = navController
}
})
}
else{ // If error in creating new user
print("error in creating new user")
print(error!)
}
})
In appDelegate
extension AppDelegate {
class func getAppDelegate() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}
Is there a cleaner, swiftier solution to handle the optional chaining happening in my code below? I'm setting up the user for CloudKit access in my custom function runCKsetup():
func runCKsetup() {
container.requestApplicationPermission(.userDiscoverability) { (status, error) in
guard error == nil else {
if let error = error as? NSError {
if let errorDictionary: AnyObject = error.userInfo as? Dictionary<String, AnyObject> as AnyObject? {
let localizedDescription = errorDictionary["NSLocalizedDescription"]! as! String!
if localizedDescription! == "This operation has been rate limited" {
// Create an alert view
let alert = UIAlertController(title: "Network Error", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Test for Connection", style: UIAlertActionStyle.default) { (action) in
self.runCKsetup()
})
self.present(alert, animated: true, completion: nil)
} else {
// Create an alert view
let alert = UIAlertController(title: "Sign in to iCloud", message: localizedDescription!, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default) { (action) in
})
self.present(alert, animated: true, completion: nil)
}
}
}
return
}
if status == CKApplicationPermissionStatus.granted {
self.container.fetchUserRecordID { (recordID, error) in
guard error == nil else {
self.presentMessageAlert((error?.localizedDescription)!, title: "Error", buttonTitle: "Ok")
return }
guard let recordID = recordID else { return }
self.container.discoverUserIdentity(withUserRecordID: recordID, completionHandler: { (info, fetchError) in
//do something with the users names: e.g. print("\(info?.nameComponents?.givenName) \(info?.nameComponents?.familyName)")
})
}
}
}
}
I am using Alamofire to update the profile through .GET method. If I use any space in any field between characters on any field its has error fatal error: unexpectedly found nil while unwrapping an Optional value.But the same URL working fine if I test it on Postman, successfully updated. so through application why it is creating error in Alamofire .
#IBAction func btnSavePressed(sender: AnyObject) {
Firstname = txtFName.text!
Lastname = txtLname.text!
Username = txtUname.text!
Phone = Int(txtPhone.text!)
DoorNo = txtDoorNo.text!
Street = txtStreet.text!
Town = txtTown.text!
Postcode = Int(txtPostCode.text!)
print(Firstname)
print(Lastname)
print(Username)
print(Phone)
print(DoorNo)
print(Street)
print(Town)
print(Postcode)
print("http://\(platform).eposapi.co.uk/?app_id=\(apiID)&app_key=\(apikey)&request=\(request)&id=\(UserID)&fname=\(Firstname)&lname=\(Lastname)&phone=\(Phone)&dno=\(DoorNo)&add1=\(Street)&add2=\(Town)&postcode=\(Postcode)")
UPDATE_data_from_URl()
}
func UPDATE_data_from_URl(){
Alamofire.request(.GET, "http://\(platform).eposapi.co.uk/?app_id=\(apiID)&app_key=\(apikey)&request=\(request)&id=\(UserID)&fname=\(Firstname)&lname=\(Lastname)&phone=\(Phone)&dno=\(DoorNo)&add1=\(Street)&add2=\(Town)&postcode=\(Postcode)", parameters: nil )
.responseJSON {
response in
print(response)
if let result: AnyObject = response.result.value {
let post: JSON = JSON(result)
let action = post["action"].boolValue
let info = post["info"].stringValue
print(action)
print(info)
if action == false{
let alert = UIAlertController(title: "", message: info, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
else{
let alert = UIAlertController(title: "Success", message: info, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default){
(action) in
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("yourtabbarvcidentifier") as! UITabBarController
vc.selectedIndex = 0
self.revealViewController().pushFrontViewController(vc, animated: true)
})
self.presentViewController(alert, animated: true, completion: nil)
Need to remove white space from your string then try it.
let linkString = "http://maps.google.com/maps?q=\(Location!)"
let address = NSURL(string:linkString.stringByReplacingOccurrencesOfString(" ", withString: ""))!
I'm trying to add error handling in creating user button in iOS project using swift and firebase:
Here's the code for the button:
#IBAction func Register(sender: AnyObject) {
if NameTF.text == "" || EmailTF.text == "" || PasswordTF.text == "" || RePasswordTF == "" || PhoneTF.text == "" || CityTF.text == ""
{
let alert = UIAlertController(title: "عذرًا", message:"يجب عليك ملىء كل الحقول المطلوبة", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
} else {
if PasswordTF.text != RePasswordTF.text {
let alert = UIAlertController(title: "عذرًا", message:"كلمتي المرور غير متطابقتين", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
} else {
FIRAuth.auth()?.createUserWithEmail(EmailTF.text!, password: PasswordTF.text!, completion: { user, error in
print(error)
if error != nil {
let errorCode = FIRAuthErrorNameKey
switch errorCode {
case "FIRAuthErrorCodeEmailAlreadyInUse":
let alert = UIAlertController(title: "عذرًا", message:"الإيميل مستخدم", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeUserNotFound":
let alert = UIAlertController(title: "عذرًا", message:"المستخدم غير موجود", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeInvalidEmail":
let alert = UIAlertController(title: "عذرًا", message:"الإيميل غير صحيح", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeNetworkError":
let alert = UIAlertController(title: "عذرًا", message:"خطأ في الاتصال بالانترنت", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
default:
let alert = UIAlertController(title: "عذرًا", message:"خطأ غير معروف", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
}
} else {
FIRAuth.auth()?.signInWithEmail(self.EmailTF.text!, password: self.PasswordTF.text!, completion: { (user: FIRUser?, error: NSError?) in
if let error = error {
print(error.localizedDescription)
} else {
self.ref.child("UserProfile").child(user!.uid).setValue([
"email": self.EmailTF.text!,
"name" : self.NameTF.text!,
"phone": self.PhoneTF.text!,
"city" : self.CityTF.text!,
])
print("Sucess")
// self.performSegueWithIdentifier("SignUp", sender: nil)
}
})
} //else
})
} //Big else
} //Big Big else
}
}//end of
I'm not sure if the syntax of the errors in switch statement is correct or not!
Because when I tested it in the simulator it always gives me the defualt case which is unknown error!
+
I could not find the syntax in the documentation:
https://firebase.google.com/docs/auth/ios/errors
So, What's the correct syntax to add error handling using new firebase and swift!
I've actually just struggled with this for quite a bit of time and found what the issue was. I've tried the code posted in an answer above and the error.code line gave me an error. It did work with error._code though. In other words, credit for the original answer to Paul with a slight modificaiton. Here's my final code (I will edit it for all errors though):
if let errCode = AuthErrorCode(rawValue: error!._code) {
switch errCode {
case .errorCodeInvalidEmail:
print("invalid email")
case .errorCodeEmailAlreadyInUse:
print("in use")
default:
print("Create User Error: \(error)")
}
}
Updated for Swift 4 + Firebase 4 + UIAlertController
extension AuthErrorCode {
var errorMessage: String {
switch self {
case .emailAlreadyInUse:
return "The email is already in use with another account"
case .userNotFound:
return "Account not found for the specified user. Please check and try again"
case .userDisabled:
return "Your account has been disabled. Please contact support."
case .invalidEmail, .invalidSender, .invalidRecipientEmail:
return "Please enter a valid email"
case .networkError:
return "Network error. Please try again."
case .weakPassword:
return "Your password is too weak. The password must be 6 characters long or more."
case .wrongPassword:
return "Your password is incorrect. Please try again or use 'Forgot password' to reset your password"
default:
return "Unknown error occurred"
}
}
}
extension UIViewController{
func handleError(_ error: Error) {
if let errorCode = AuthErrorCode(rawValue: error._code) {
print(errorCode.errorMessage)
let alert = UIAlertController(title: "Error", message: errorCode.errorMessage, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
}
Usage example:
Auth.auth().signIn(withEmail: email, password: password, completion: { (user, error) in
if error != nil {
print(error!._code)
self.handleError(error!) // use the handleError method
return
}
//successfully logged in the user
})
Even though this has been answered correctly, wanted to share a nice implementation for this we added to our project.
This can be done for other error types as well, but we just needed it for the FIRAuthErrorCodes.
If you extend FIRAuthErrorCode to have a variable errorMessage of type string, you can have your own error messages for the users:
extension FIRAuthErrorCode {
var errorMessage: String {
switch self {
case .errorCodeEmailAlreadyInUse:
return "The email is already in use with another account"
case .errorCodeUserDisabled:
return "Your account has been disabled. Please contact support."
case .errorCodeInvalidEmail, .errorCodeInvalidSender, .errorCodeInvalidRecipientEmail:
return "Please enter a valid email"
case .errorCodeNetworkError:
return "Network error. Please try again."
case .errorCodeWeakPassword:
return "Your password is too weak"
default:
return "Unknown error occurred"
}
}
}
You could customize only some as we have above and group the rest under "Unknown error".
With this extension you can handle an error as shown in Vladimir Romanov's answer:
func handleError(_ error: Error) {
if let errorCode = FIRAuthErrorCode(rawValue: error._code) {
// now you can use the .errorMessage var to get your custom error message
print(errorCode.errorMessage)
}
}
FIRAuthErrorCode is an int enum not a string enum. Do the following:
if let error = error {
switch FIRAuthErrorCode(rawValue: error.code) !{
case .ErrorCodeInvalidEmail:
More info in this answer.
I am using Swift 5 and Firebase 6.4.0 and for me, none of the above really worked. After trying around a bit I came up with this:
Auth.auth().createUser(withEmail: emailTextfield.text!, password: passwordTextfield.text!) { (user, error) in
if error!= nil{
let alert = UIAlertController(title: "Error", message: error!.localizedDescription, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true)
}