user Log In, let the users in without errors (SWIFT) (Parse) - swift

i'm making an app that required Logging In. the problem is when i run my app to try it and type wrong user info it proceed to the next view controller without giving the error !. Heres my code i don't whats the problem !
{
#IBOutlet weak var ActivityIndicator: UIActivityIndicatorView!
#IBOutlet weak var Message: UILabel!
#IBOutlet weak var UsernameTextField: UITextField!
#IBOutlet weak var PasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
ActivityIndicator.hidden = true
ActivityIndicator.hidesWhenStopped = true
// Do any additional setup after loading the view.
}
#IBAction func LogInButtonTapped(sender: AnyObject) {
LogIn()
}
func LogIn() {
// Start activity indicator
ActivityIndicator.hidden = false
ActivityIndicator.startAnimating()
// if there is a user
var user = PFUser()
user.username = UsernameTextField.text
user.password = PasswordTextField.text
PFUser.logInWithUsernameInBackground(UsernameTextField.text, password:PasswordTextField.text) {
(user: PFUser?, error: NSError?) -> Void in
if user != nil {
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("LogInToHomeVC", sender: self)}
println("Logged In")
} else {
self.ActivityIndicator.stopAnimating()
if let Message: AnyObject = error!.userInfo!["error"] {
self.Message.text = "\(Message)"}
println("Could Not Find User")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
so the question is how to let the user try again and not let him enter the Home Page?

Related

Force unwrapping nil optional for UIImageView when transitioning to view controller

I'm running into an error when transitioning to view controllers by overriding the built-in prepare() function in Swift. I have a UIImageView for backgrounds on my screens. Here is the code for two of the view controllers in question.
import UIKit
import FirebaseAuth
class HomeVC: UIViewController {
#IBOutlet weak var signOutButton: UIButton!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendsNavButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var profileNavButton: UIButton!
#IBOutlet weak var bumpButton: UIButton!
#IBOutlet weak var welcomeLabel: UILabel!
#IBOutlet weak var doNotDisturbLabel: UILabel!
#IBOutlet weak var doNotDisturbButton: UIButton!
var userName = ""
var dndIsOn: Bool = false
#IBAction func dndToggled(_ sender: Any) {
dndIsOn = !dndIsOn
User.current.available = !dndIsOn
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).updateData([Constants.Firestore.Keys.available : !dndIsOn])
if dndIsOn {
print("DND is on!")
setupDNDUI()
} else if !dndIsOn {
print("DND is off!")
setupActiveUI()
}
}
#IBAction func signOutTapped(_ sender: Any) {
let firAuth = Auth.auth()
do {
try firAuth.signOut()
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
print("Successfully signed out")
}
#IBAction func bumpTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toCall, sender: self)
}
#IBAction func friendsNavTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toFriends, sender: self)
}
#IBAction func profileNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(ProfileVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
doNotDisturbLabel.isHidden = true
if !userName.isEmpty {
welcomeLabel.text = "Welcome Back, " + userName + "!"
} else {
welcomeLabel.text = ""
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let friendsVC = segue.destination as? FriendsVC else {
return
}
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).getDocument { (snapshot, err) in
if let err = err {
print(err.localizedDescription)
} else {
let data = snapshot!.data()!
let requests = data[Constants.Firestore.Keys.requests] as? [String]
if let requests = requests {
friendsVC.requests = requests
}
}
}
}
class FriendsVC: UIViewController {
//var friends: [Friend] = User.current.friends
var friends: [User] = []
var requests: [String]?
#IBOutlet weak var requestsNumberLabel: UILabel!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendRequestsButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var friendsTitle: UILabel!
#IBOutlet weak var friendTableView: UITableView!
#IBOutlet weak var addFriendButton: UIButton!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint!
#IBAction func friendRequestsTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toRequests, sender: self)
}
#IBAction func homeNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(HomeVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
friendTableView.backgroundView?.backgroundColor = .white
friendsTitle.isHidden = false
UserService.getUserArray(uids: User.current.friendUids, completion: { (users) in
guard let users = users else {
print("User has no friends")
return
}
self.friends = users
self.friendTableView.reloadData()
})
guard let requests = self.requests else {
friendRequestsButton.isHidden = true
requestsNumberLabel.isHidden = true
self.tableViewTopConstraint.constant = 0
return
}
requestsNumberLabel.text = requests.count.description
// Do any additional setup after loading the view.
friendTableView.delegate = self
friendTableView.dataSource = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let homeVC = segue.destination as? HomeVC {
homeVC.userName = User.current.firstName
} else if let requestsVC = segue.destination as? RequestsVC {
UserService.getUserArray(uids: self.requests!) { (requesters) in
if let requesters = requesters {
requestsVC.requesters = requesters
}
}
}
}
}
When my app loads into the home screen, there is no problem, and when a button is tapped to transition to FriendsVC, there is no problem. However, when I try to initiate the transition from HomeVC to ProfileVC or from FriendVC to HomeVC, I get the error: "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" at the self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill lines in my viewDidLoad methods. These segues have something in common in that these are the ones where I override the prepare() function, but I'm not sure what I'm doing wrong

Taking Facebook values (email, name, etc) from one view controller and transferring them to another one

So I'm currently designing an application and am working on the account registration. I've implemented Facebook login into it but I am having trouble taking a user's Facebook information and transferring it to the next page, where, ideally, the fields for name and email would be filled with those values received from Facebook.
The initial page with the Facebook login looks like this:
class RegisterVC: UIViewController, FBSDKLoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let loginButton = FBSDKLoginButton()
view.addSubview(loginButton)
loginButton.frame = CGRect(x: 82, y: 325, width: view.frame.width - 210, height: 59)
loginButton.delegate = self
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("Did log out of facebook")
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil {
print(error)
return
}
print("Successfully logged in")
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start {(connection, result, err) in
if err != nil {
print("Failed to start graph request", err)
return
} else {
guard let data = result as? [String:Any] else {return}
let fbEmail = data["email"]
let fbName = data["name"]
}
print(result)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//get destination view an set the fullname
let vc = segue.destination as? CreateAccountVC
vc?.email = self.fbEmail
vc.fullname = self.fbName
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
And the next view controller, a typical registration page, has these text fields:
#IBOutlet weak var fullname: UITextField!
#IBOutlet weak var username: UITextField!
#IBOutlet weak var age: UITextField!
#IBOutlet weak var email: UITextField!
#IBOutlet weak var verifyEmail: UITextField!
#IBOutlet weak var password: UITextField!
#IBOutlet weak var verifyPassword: UITextField!
I have no idea how to take the values from Facebook and put them into these text entry boxes. I'm very new to programming so any help would be much appreciated, thanks!
First, store the FB values in a var(s) you can access later.
Next, You can set the values for your next view before you transition. For example if you are using a segue, you can do it in the prepareForSegue like this:
class RegisterVC: UIViewController, FBSDKLoginButtonDelegate {
var fbName:String?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//get destination view an set the fullname
let vc=segue.destination as? MyCustomVC
vc.fullName=self.fbName
}

Writing User Data to Firebase After Creating New User Account

I am currently trying to write the users information to firebase's database after using the create user function FIRAuth.auth()?.createUser
Under this function I attempt to insert the data into the database like this:
FIRAuth.auth()?.createUser(withEmail: self.emailField.text!, password: self.passwordField.text!) { (user, error) in
if error == nil
{
let email = self.emailField.text
let firstName = self.firstnameField.text
let lastName = self.lastnameField.text
self.ref.child((user?.uid)!).setValue(["firstName": firstName,"lastName": lastName,"email": email])
self.performSegue(withIdentifier: "createaccountLandingPage", sender: sender)
}
It also may be important to mention that under my view controller I create the reference to the database using:
var ref = FIRDatabase.database().reference().child("users") //root database
My outlets are all correct, but I am getting this error:
Thread 1: signal SIGABRT
Any suggestions on what I may be doing incorrectly?
EDIT** Here is all my code in the signup view controller
import UIKit
import Firebase
import FirebaseDatabase
class CreateAccountViewController: UIViewController {
var ref = FIRDatabase.database().reference().child("users") //root database
#IBOutlet weak var firstnameField: UITextField!
#IBOutlet weak var lastnameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var confirmpasswordField: UITextField!
#IBOutlet weak var createAccountButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
if (FIRAuth.auth()?.currentUser) != nil
{
}
else
{
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func createAccountAction(_ sender: AnyObject)
{
if self.confirmpasswordField.text != self.passwordField.text
{
}
else
{
FIRAuth.auth()?.createUser(withEmail: self.emailField.text!, password: self.passwordField.text!) { (user, error) in
if error == nil
{
let user = FIRAuth.auth()?.currentUser.uid
let email = self.emailField.text
let firstName = self.firstnameField.text
let lastName = self.lastnameField.text
self.ref.child("users").child("\(user)").setValue(["firstName": firstName,"lastName": lastName,"email": email])
self.performSegue(withIdentifier: "createaccountLandingPage", sender: sender)
}
else
{
let alertController = UIAlertController(title: "Oops!", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
EDIT*** here is a screenshot of the error
EDIT**** here is a screenshot of my podfile and when it is updated I recieve no errors in the terminal.
EDIT***** Screenshots of console.
1stScreenshotConsole
2ndScreenshotConsole
You have to create a reference to your database like this
Var ref: FIRDatabaseReference!
Then you initialize your database in your viewDidLoad like this
Ref = FIRDatabase.database().reference()
I wrote the whole code below, excuse the syntax errors because I am answering your question on an iPad.
import UIKit
import Firebase
import FirebaseDatabase
class CreateAccountViewController: UIViewController {
var ref = FIRDatabaseReference! //create a reference for your database
#IBOutlet weak var firstnameField: UITextField!
#IBOutlet weak var lastnameField: UITextField!
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passwordField: UITextField!
#IBOutlet weak var confirmpasswordField: UITextField!
#IBOutlet weak var createAccountButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
//initialize your database
ref = FIRDatabase.database().reference()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func createAccountAction(_ sender: AnyObject)
{
if self.confirmpasswordField.text != self.passwordField.text
{
}
else
{
FIRAuth.auth()?.createUser(withEmail: self.emailField.text!, password: self.passwordField.text!) { (user, error) in
if error == nil
{
let user = FIRAuth.auth()?.currentUser.uid //get the users UID after registering
let email = self.emailField.text
let firstName = self.firstnameField.text
let lastName = self.lastnameField.text
self.ref.child("users").child("\(user!)").setValue(["firstName": "\(firstName!)", "lastName": "\(lastName!)", "email": "\(email!)"])
self.performSegue(withIdentifier: "createaccountLandingPage", sender: sender)
}
else
{
let alertController = UIAlertController(title: "Oops!", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}

Delegate Method is not called in Swift?

I want to pass a Bool value from on view controller to another without the help of segues. So i referred & got Delegates.
I have applied delegates in my App. But the Delegate method is not being called. I don't know where i am making the mistake.
So Please help me.
MainViewController
class MainViewController: UIViewController, WriteValueBackDelegate {
#IBOutlet weak var LoginButton: UIButton!
var LoggedInL :Bool?
override func viewDidLoad() {
super.viewDidLoad()
}
func writeValueBack(value: Bool) {
println("Delegate Method")
if (value == true){
LoginButton.setTitle("My Profile", forState:UIControlState.Normal)
}
}
Second View Controller
class LoginController: UIViewController {
#IBOutlet weak var LoginLabel: UILabel!
#IBOutlet weak var email: UITextField!
#IBOutlet weak var pwd: UITextField!
var LoggedInL :Bool?
var mydelegate: WriteValueBackDelegate?
override func viewDidLoad() {
super.viewDidLoad() }
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func onSubmit(sender: AnyObject) {
Alamofire.request(.GET, "http://www.jive.com/index.php/capp/user_verification/\(email.text)/\(pwd.text)")
.responseJSON { (_, _, data, _) in
println(data)
let json = JSON(data!)
let name = json["first_name"].stringValue
let status = json["valid_status"].intValue
println(status)
var e = self.email.text
println(e)
self.LoginLabel.text = "Hey \(name)!"
if status == 1{
println("Correect")
self.LoggedInL = true
self.mydelegate?.writeValueBack(true)
}else {
self.LoggedInL = false
println("Error")
}
}
navigationController!.popViewControllerAnimated(true)
}
}
protocol WriteValueBackDelegate {
func writeValueBack(value: Bool)
}
you didn't initialize the delegate, and no need to, delegates are usually for async callbacks. do that instead:
class MainViewController: UIViewController {
static var sharedInstace : MainViewController?;
#IBOutlet weak var LoginButton: UIButton!
var LoggedInL :Bool?
override func viewDidLoad() {
super.viewDidLoad()
MainViewController.sharedInstace = self; //this is better from init function
}
func writeValueBack(value: Bool) {
println("Delegate Method")
if (value == true){
LoginButton.setTitle("My Profile", forState:UIControlState.Normal)
}
}
}
in login view controller
MainViewController.sharedInstance?.writeValueBack(true)
In MainViewControlleryou need a reference of the LoginController instance maybe with an IBOutlet and then set the delegate in viewDidLoad
#IBOutlet weak var loginController : LoginController!
override func viewDidLoad() {
super.viewDidLoad()
loginController.mydelegate = self
}

Navigation Controller Error

I have a navigation controller and I want the title to have a custom font. I have tried to do this but when it runs I get Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP.subcode=0x0)
Here is my code.
import UIKit
class PriceCheckSpreadsheetViewController: UIViewController {
#IBOutlet weak var SpreadsheetView: UIWebView!
#IBOutlet weak var Loading: UIActivityIndicatorView!
#IBOutlet weak var BackButton: UIBarButtonItem!
#IBOutlet weak var ForwardButton: UIBarButtonItem!
#IBOutlet weak var NaviBar: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let url = "http://www.backpack.tf/pricelist/spreadsheet"
let requestURL = NSURL(string: url)
let request = NSURLRequest(URL: requestURL!)
SpreadsheetView.loadRequest(request)
self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "TF2Build", size: 12)!]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func webViewDidStartLoad(_ : UIWebView) {
Loading.startAnimating()
NSLog("Loading")
}
func webViewDidFinishLoad(_ : UIWebView) {
Loading.stopAnimating()
NSLog("Done")
if SpreadsheetView.canGoBack {
BackButton.enabled = true
}
else {
BackButton.enabled = false
}
if SpreadsheetView.canGoForward {
ForwardButton.enabled = true
}
else {
ForwardButton.enabled = false
}
}
#IBAction func Reload(sender: AnyObject) {
SpreadsheetView.reload()
}
#IBAction func Back(sender: AnyObject) {
SpreadsheetView.goBack()
}
#IBAction func Forward(sender: AnyObject) {
SpreadsheetView.goForward()
}
}