Function moveToHome gives error when stating the viewcontroller class. Use of undeclared type 'HomeViewController'. I set the class of the view controller to HomeViewController but it is not being recognized.
import Foundation
import UIKit
import Firebase
import SwiftKeychainWrapper
import FirebaseAuth
import FirebaseFirestore
class SignUpEmail: UIViewController {
#IBOutlet weak var Email: UITextField!
#IBOutlet weak var Password: UITextField!
#IBOutlet weak var Firstname: UITextField!
#IBOutlet weak var Lastname: UITextField!
#IBOutlet weak var City: UITextField!
#IBOutlet weak var Street: UITextField!
#IBOutlet weak var Gender: UITextField!
#IBOutlet weak var SignupButton: UIButton!
#IBOutlet weak var errorLAbel: UILabel!
var userUid: String!
override func viewDidLoad() {
super.viewDidLoad()
SignupButton.layer.cornerRadius = 15
errorLAbel.alpha = 0
}
// Check fields, If everything is correct returns Nil otherwise returns error.
func validateFields() -> String? {
if Email.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Password.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Firstname.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Lastname.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
City.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Street.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Gender.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
return "Please fill in all fields."
}
// Check if password is secure
let cleanedPassword = Password.text!.trimmingCharacters(in: .whitespacesAndNewlines)
if Utilities.isPasswordValid(cleanedPassword) == false {
// Password isn't secure enough
return "Please make sure your password is at least 8 characters, contains a special character and a number."
}
return nil
}
#IBAction func SignupTapped(_ sender: Any) {
//Validate
let error = validateFields()
if error != nil {
// Something is wrong with the fields
showError(error!)
}
else {
// Create User
// Create clean versions of data
let lastname = Lastname.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let firstname = Firstname.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let email = Email.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = Password.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let city = City.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let street = Street.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let gender = Gender.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
//check for errors
if err != nil {
// There was an error creating the user
self.showError("Error Creating User")
}
else {
//User was creating successfully now store
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["firstname":firstname, "lastname":lastname, "City": city, "Street": street, "Gender":gender, "uid": result!.user.uid]) { (Error) in
if error != nil {
self.showError("Error saving user data")
}
}
// Move to homescreen
self.moveToHome()
}
}
}
}
func showError(_ message:String) {
errorLAbel.text = message
errorLAbel.alpha = 1
}
func moveToHome() {
let storyboard = UIStoryboard(name: "Main.storyboard", bundle: nil)
let homeViewController = storyboard?.instantiateViewController(identifier: "HomeVC") as? HomeViewController //This part gives error
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
}
}
(Ignore had to add extra text to be able to post)
try:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
uses "Main" instead of "Main.storyboard"
and make sure that the StoryboadID has been set
Related
I am trying to check for empty fields in the login page of IOS app using swift story board. The code is pasted below:
#IBOutlet weak var firstNameTextField: UITextField!
if (firstNameTextField.text?.isEmpty)! ||
(lastNameTextField.text?.isEmpty)! ||
(emailTextField.text?.isEmpty)! ||
(passwordTextField.text?.isEmpty)!{
userMessage(userMessage: "All fields are required")
return
}
I am getting the error:
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Can someone let me know what I am doing wrong here
Please make sure that all the outlets are connected properly.
Problem
The possible cause of the crash can be..
The result of firstNameTextField.text?.isEmpty may be null and you have used ! to unwrap so it get crashed
Or may possible that the IBOutlet is not connected to view controller in storyboard.
Solution
You can user if-let like below...
let fanme = firstNameTextField.text ?? ""
let lname = lastNameTextField.text ?? ""
let email = emailTextField.text ?? ""
let password = passwordTextField.text ?? ""
if fname.isEmpty || lname.isEmpty || email.isEmpty || password.isEmpty {
userMessage(userMessage: "All fields are required")
return
}
You must unwrap your variable and after check if tf are empty:
#IBOutlet weak var firstNameTextField: UITextField!
#IBOutlet weak var lastNameTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
Now write the func to check:
#objc func chekTfIsEmpty () {
guard let firstTF = firstNameTextField.text else { return } // unwrapped
guard let lastNameTF = lastNameTextField.text else { return } // unwrapped
guard let emailTF = emailTextField.text else { return } // unwrapped
guard let passTF = passwordTextField.text else { return } // unwrapped
if firstTF.isEmpty ||
lastNameTF.isEmpty ||
emailTF.isEmpty ||
passTF.isEmpty {
userMessage(userMessage: "All fields are required")
return
} else {
// do your stuff here
}
}
after that call the this function with your login button...
I have made an sign up and also login and it works! but now I want to edit the data in the Firebase. Can anyone help me how to do it? Thanks you
Here the Sign Up View Controller
import UIKit
import FirebaseAuth
import FirebaseFirestore
class SignupViewController: UIViewController {
#IBOutlet weak var FirstNameTextfield: UITextField!
#IBOutlet weak var LastNameTextfield: UITextField!
#IBOutlet weak var EmailTextField: UITextField!
#IBOutlet weak var PasswordTextfield: UITextField!
#IBOutlet weak var SignUpButton: UIButton!
#IBOutlet weak var ErrorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setUpElements()
}
func setUpElements(){
ErrorLabel.alpha = 0
}
func validateFields()->String? {
//check that all the fields are fill
if FirstNameTextfield.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" || LastNameTextfield.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" || EmailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" || PasswordTextfield.text?.trimmingCharacters(in: .whitespacesAndNewlines) == ""
{
return "Please fill up all the Fields"
}
//check the password if the password is secure
let cleanedPassword = PasswordTextfield.text!.trimmingCharacters(in: .whitespacesAndNewlines)
if Utilities.isPasswordValid(cleanedPassword) == false{
return "Please enter at least 8 characters, with a number and characteristic symbol"
}
return nil
}
#IBAction func SignUpTap(_ sender: Any) {
let error = validateFields()
if error != nil{
showError(message: error!)
}
else {
let FirstName = FirstNameTextfield.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let LastName = LastNameTextfield.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let Email = EmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let Password = PasswordTextfield.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().createUser(withEmail: Email, password: Password) { (result, err) in
if err != nil{
self.showError(message: "Error creating the user")
}
else {
let db = Firestore.firestore()
db.collection("users").addDocument(data:["FirstName":FirstName, "LastName":LastName, "uid": result!.user.uid]) { (Error) in
if error != nil{
self.showError(message: "Cannot saving user data" )
}
}
self.transitionToHomePage()
}
}
}
}
func showError( message:String){
ErrorLabel.text = message
ErrorLabel.alpha = 1
}
func transitionToHomePage(){
let TabHomeViewController = storyboard?.instantiateViewController(identifier: Constrants.Storyboard.TabHomeViewController) as? TabHomeViewController
view.window?.rootViewController = TabHomeViewController
view.window?.makeKeyAndVisible()
}
}
Here my login VC
#IBAction func LoginTap(_ sender: Any) {
let Email = EmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let Password = PasswordTextfield.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().signIn(withEmail: Email, password: Password) { (result, error) in
if error != nil{
self.ErrorLabel.text = error!.localizedDescription
self.ErrorLabel.alpha = 1
}
else{
let TabHomeViewController = self.storyboard?.instantiateViewController(identifier: Constrants.Storyboard.TabHomeViewController) as? UITabBarController
self.view.window?.rootViewController = TabHomeViewController
self.view.window?.makeKeyAndVisible()
}
And here my Account View Controller
import UIKit
import FirebaseAuth
import FirebaseFirestore
import Firebase
class AccountViewController: UIViewController {
#IBOutlet weak var FNameTextField: UITextField!
#IBOutlet weak var LNameTextField: UITextField!
#IBOutlet weak var EmailTextField: UITextField!
#IBOutlet weak var PasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func logoutbutton(_ sender: Any) {
do{
try Auth.auth().signOut()
performSegue(withIdentifier: "signout", sender: nil)
}
catch{
print(error)
}
}
}
You can use this function:
func updateFirestoreUserProfile(uid: String, data: [String:Any]) {
Firestore.firestore().collection("users").document(uid).updateData(data) { err in
if let err = err {
print("Error updating document: \(err) ")
}
else {
print("Document successfully updated")
}
}
}
You can use the function like this:
let data = [
"FirstName": name,
"LastName": surname
]
updateFirestoreUserProfile(uid: user.uid, data: data)
I've created a SignUp page (ViewController) and on gender selection I'm using a UISegmentedControl for "male", "female", "indifferent". But how can I get the value from the UISegmentedControl and put in a dictionary? I'm using a custom Dictionary<String, String> = [:] for signup but the UISegmentedControl is not a string (obviously) and I get the error:
Cannot assign value of type 'UISegmentedControl' to type 'String'
How can I convert the result of UISegmentedControl to receive those values?
import UIKit
import FirebaseAuth
import Firebase
class SignUpViewController: UIViewController{
#IBOutlet weak var nameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var birthdayField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var confirmpasswordField: UITextField!
#IBOutlet weak var instagramuserField: UITextField!
#IBOutlet weak var generoSegmentControl: UISegmentedControl!
#IBOutlet weak var DatePickerDate: UITextField!
#IBOutlet weak var signupOutlet: UIButton!
#IBAction func signupAction(_ sender: Any) {
if let name = self.nameField.text {
if let email = self.emailField.text {
if let birthday = self.birthdayField.text {
if let password = self.passwordField.text {
if let confirmpassword = self.confirmpasswordField.text {
if let instagramuser = self.instagramuserField.text {
if let gender = self.generoSegmentControl {
if password == confirmpassword {
print("Senhas iguais, podemos seguir")
}else {
print("As senhas precisam ser iguais")
}
self.auth.createUser(withEmail: email, password: password) { (user, error) in
if error == nil {
var user: Dictionary<String, String> = [:]
user["nome"] = name
user["email"] = email
user["nascimento"] = birthday
user["instagram"] = instagramuser
user["genero"] = gender
//Encoding email for Base 64
let key = Base64().encodingStringBase64(text: email)
let users = self.database.reference().child("usuarios")
users.child(key).setValue(user)
print("Sucesso ao cadastrar usuário!")
}else{
print("Erro ao cadastrar usuário, tente novamente!")
}
}
}else {
print("Escolha seu genero")
}
}else{
print("O campo usuário do instagram esta vazio")
}
}else{
print("As senhas não conferem")
}
}else{
print("Digite uma senha")
}
}else{
print("Digite a data do seu nascimento")
}
}else{
print("Digite seu e-mail")
}
}else{
print("Digite seu nome")
}
}
#IBAction func generoAction(_ sender: Any) {
let genIndex = generoSegmentControl.selectedSegmentIndex
switch genIndex {
case 0:
print("Homem")
case 1:
print("Mulher")
case 2:
print("Indiferente")
default:
print("Nada selecionado")
}
}
}
You get the segmentedControl in your code, but not it's selectedSegmentIndex property. Then after receiving the selectedSegmentIndex, you should get the title for that index from control. Update your code with following:
if let gender = self.generoSegmentControl {
Either change it to:
let genderIndex = self.generoSegmentControl.selectedSegmentIndex
if let gender = self.generoSegmentControl.titleForSegment(at: genderIndex) {
}
OR change the way you update dictionary:
let index = gender.selectedSegmentIndex
if let segmentTitle = gender.titleForSegment(at: index) {
user["nome"] = name
user["email"] = email
user["nascimento"] = birthday
user["instagram"] = instagramuser
user["genero"] = segmentTitle
}
I think i have been coding for to many hours and i am getting delirious. I need a second eye to view my obvious problems.
-My function called ( #IBAction func SignIn ) at the bottom of the code ends after a single click. I click once works fine, click twice the code gets terminated and is done. How can I re-iterate this function so I can have it keep going every time I click the IB action button.
import UIKit
import Firebase
import FirebaseDatabase
import KeychainSwift
class SignUpController: UIViewController {
//Variable List
var ref = FIRDatabase.database().reference() //Data Base Initialization
public var validPassword = false //Both passwords match
//Represent Red or Green password Image
#IBOutlet weak var myImageView: UIImageView!
//INPUT - User Input from UI Text Fields
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var passwordConfirmField : UITextField!
#IBOutlet weak var usernameField : UITextField!
#IBOutlet weak var nameField : UITextField!
/****************************View Loads*****************************/
override func viewDidLoad() {
super.viewDidLoad()
ref = FIRDatabase.database().reference()
myImageView.image = UIImage(named: "confirmPaswordRed")
}
//PROCESS - Checks is user has already been logged in
override func viewDidAppear(_ animated: Bool) {
let currentUser = FIRAuth.auth()?.currentUser
if currentUser != nil {
performSegue(withIdentifier: "SignIn", sender: nil)
}
}
/******************************************************************/
/****************************Functions*****************************/
func CompleteSignIn(id: String){
let keyChain = DataService().keyChain
keyChain.set(id , forKey: "uid")
}
//Send all data text fields to Firebase Database
func sendToFirebaseDatabase(userID : String) {
let name : String = self.nameField.text!
let username : String = self.usernameField.text!
let userEmail : String = self.emailField.text!
let userPassword : String = self.passwordField.text!
self.ref.child("Users").child(userID).setValue(["Name": name, "Username": username, "Email": userEmail, "Password" : userPassword])
}
//Determines Red or Green password validation
#IBAction func passwordConfirmImage(_ sender: UITextField) {
let userConfirmPassword : String? = self.passwordConfirmField.text!
let userPassword : String? = self.passwordField.text!
if (userPassword == userConfirmPassword) && (userPassword != "") {
validPassword = true
let greenImage = UIImage(named: "confirmPasswordGreen")
myImageView.image = greenImage
print("Function entry test")
}else {
myImageView.image = UIImage(named: "confirmPaswordRed")
validPassword = false
}
}
/******************************************************************/
/****************************IBACTIONS*****************************/
//If SignUp button is pressed user will be directed to sign up page
#IBAction func LoginPressed(_ sender: Any) {
self.performSegue(withIdentifier: "BackToLogin", sender: nil)
}
/*Sign In Action: If both password and email contain text lets put them into string variables
called email & password. Creates user and authorizes sign in */
#IBAction func SignIn(_ sender: Any){
if let email = emailField.text, let password = passwordField.text {
FIRAuth.auth()?.signIn(withEmail: email, password: password) { (user, error) in
if ((error == nil) && (self.validPassword) == true) {
self.CompleteSignIn(id: user!.uid) //Completes Database Sign in
print("Sign in Test")
self.performSegue(withIdentifier: "SignIn", sender: nil)
} else {
FIRAuth.auth()?.createUser(withEmail: email, password: password) { (user, error) in
if ((error == nil) && (self.validPassword) == false) {
Alerts().invalidSignUpAlert(sender: self) //Alert for invalid email & Password
print("cant sign in user") //Programmer Debugging
} else {
if self.validPassword == true{
let userID : String = user!.uid //initialize userId String
self.sendToFirebaseDatabase(userID: userID) //Call sendToFirebaseDatabase
self.performSegue(withIdentifier: "SignIn", sender: nil) //goto Login Page
}
}
}
}
}
}
}
}
I'm trying to implement one simple thing - to switch the string value by switching UISwitch.
But, I can get, what is wrong
func switchIsChanged(interestedIn: UISwitch) {
if interestedIn.on == true {
print("UISwitch is ON")
} else {
print("UISwitch is OFF")
}
}
if self.Gender.text == "male" {
switchIsChanged(self.interestedIn)
}
I can show the whole code if necessary. I just taking data from Facebook, understand the gender if user, and the set the value interestedIn depending on his or her gender.
import UIKit
import FBSDKShareKit
import FirebaseDatabase
import FirebaseAuth
import Firebase
class Settings: UIViewController {
#IBOutlet weak var UserImage: UIImageView!
#IBOutlet weak var UserName: UILabel!
#IBOutlet weak var UserSurname: UILabel!
#IBOutlet weak var Gender: UILabel!
#IBOutlet weak var interestedIn: UISwitch!
#IBOutlet weak var GenderofInsterest: UILabel!
var pictureURL : String?
var interest = ""
override func viewDidLoad() {
super.viewDidLoad()
let paramets = ["fields": "email, first_name, last_name, picture.type(large), gender"]
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: paramets)
graphRequest.startWithCompletionHandler({
(connection, result, error) -> Void in
if error != nil {
print (error)
}
if let first_name = result["first_name"] as? String {
self.UserName.text = first_name
}
if let last_name = result["last_name"] as? String {
self.UserSurname.text = last_name
}
if let picture = result["picture"] as? NSDictionary, data = picture["data"] as? NSDictionary, pictureUrl = data["url"] as? String {
self.pictureURL = pictureUrl
let fbUrl = NSURL(string: pictureUrl)
if let picData = NSData(contentsOfURL: fbUrl!) {
self.UserImage.image = UIImage(data: picData)
}
}
if let gender = result["gender"] as? String {
self.Gender.text = gender
}
let people = ProfileClass()
people.profileName = self.UserName.text
people.profileGender = self.Gender.text
people.profileSurname = self.UserSurname.text
people.profilePhotoUrl = self.pictureURL
people.SaveUser()
func switchIsChanged(interestedIn: UISwitch) {
if interestedIn.on == true {
print("UISwitch is ON")
} else {
print("UISwitch is OFF")
}
}
if self.Gender.text == "male" {
switchIsChanged(self.interestedIn)
}
})
}}
As #ILideTau mentioned above, you should not directly work with UISwitch states, instead of that, just create a Bool variable, that will hold your switch state, and update UI when you change its state in didSet { } closure:
#IBOutlet weak var interestedInSwitch: UISwitch!
var interstedInState: Bool = false {
didSet {
interestedInSwitch.on = interstedInState
}
}
func updateInterstedInState(newValue: Bool) {
interstedInState = newValue
}