How to create an if statement with an array in swift? - ios

I am trying to make an app that uses a login system. I have created an array for both the usernames and the passwords. But I need to test if the password is correct or not. How can I create an if statement that tests for values that are inside of an array? Here is my code in case you need it.
import UIKit
var namesArray = [String]()
var passWordArray = [String]()
class ViewController: UIViewController {
var username = "Ege"
var password = "Gürkan"
var trueFalse = true
#IBOutlet weak var idTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var trueWrongLabel: UILabel!
#IBAction func buttonPressed(sender: AnyObject) {
if idTextField.text == "Ege" && passwordTextField.text == "Gürkan" {
self.performSegueWithIdentifier("geçiş", sender: self)
} else {
trueWrongLabel.text = "Wrong id/pw"
idTextField.resignFirstResponder()
passwordTextField.resignFirstResponder()
trueWrongLabel.textColor = UIColor.redColor()
idTextField.text = nil
passwordTextField.text = nil
}
}
override func viewDidLoad() {
super.viewDidLoad()
NSUserDefaults.standardUserDefaults().setObject(namesArray, forKey: "nameArray")
var recalledNameArray = NSUserDefaults.standardUserDefaults().objectForKey("nameArray")! as NSArray
NSUserDefaults.standardUserDefaults().setObject(passWordArray, forKey: "passWordArray")
var recalledPassWordArray: AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("passWordArray")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In the line that says: if isTextField.text == "Ege"
I want to test if there is a value for what has the user just entered in the textfield. How can I do it?
PS: I am very new to programming in general so please don't use complicated terms while explaining

This is beginning programming stuff.
There are lots of ways to do this.
One straightforward way would be to create a struct that contains a name property and a password property. Then create an array of the structs. When the user enters a username and password, use a filter command to find the structure that contains the matching username, and then check to see if the password is correct.
If you're not comfortable with the Swift filter function (I haven't used it yet myself) then you could also loop through the array yourself looking for matches.

Why you are using Array for userName and Array for Password?
How can you know if that password for that userName?
I advice you to use Dictionary it is the best solution for you.
so one Dictionary for username and password and the values will be:
key:value
Ege:Gürkan
and the code will be:
for (key,value) in dic
{
if (key == idTextField.text && value == passwordTextField.text)
{
println("true")
}
}
I hope this is what you want!.

Related

How do I find the Max from a group of user inputed Ints using Xcode 11 and swift

Here's what I have so far:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var game1: UITextField!
#IBOutlet weak var game2: UITextField!
#IBOutlet weak var game3: UITextField!
#IBOutlet weak var series: UILabel!
#IBOutlet weak var average: UILabel!
#IBOutlet weak var high: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func calculate(_ sender: Any) {
let game1Results = Int(game1.text!)
let game2Results = Int(game2.text!)
let game3Results = Int(game3.text!)
let gameResultsArray = [game1Results, game2Results, game3Results]
high.text = "\(gameResultsArray.max())"
}
}
I've been trying to use the .max function but I'm getting errors stating I need to refer to conform to "Comparable". I'm pretty new to swift, any help will be much appreciated.
It happens because you try to compare values of optional Int (Int?)
First of all, you should know that not each String can be converted to an Int
E.g. '42' will be converted correctly, but 'ie42zx' can't be converted to and Int - that's why Int(String) function returns optional Int (Int?)
'Optional' property says like 'i can have a value, but I can also be nil'. That's why you should unwrap optionals in your code
First, I suggest to avoid force unwraping here.
let game1Results = Int(game1.text!)
It can be done like that:
guard
let text1 = game1.text,
let text2 = game2.text,
let text3 = game3.text
else { return }
You should do that because not every text field contains text, so textField.text property returns an optional String?
Then you can convert your String results to an Int and unwrap these results before compare:
guard
let game1Results = Int(text1),
let game2Results = Int(text2),
let game3Results = Int(text3)
else { return }
I would suggest to read more about optionals in swift and unwrapping (see Optionals paragraph)
I believe your issue is that the Int constructor with a string returns an optional integer value. You're trying to take the max of a bunch of optionals, so it cant figure it out.
You can use the compactMap function on your array before calling max() to filter out the nil values.
gameResultsArray.compactMap{ $0 }.max()

Storing user input from text field to Parse Database

I am trying to store the information a user inputs for the signup page into a parse database, but can't seem to figure out how to do it.
class ViewController: UIViewController {
#IBOutlet var fullnameField: UITextField!
#IBOutlet var emailAddressField: UITextField!
#IBOutlet var usernameField: UITextField!
#IBOutlet var passwordField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let userFullname = fullnameField.text
let userEmailAddress = emailAddressField.text
let userName = usernameField.text
let userPassword = passwordField.text
let User = PFObject(className: "User")
User["FullName"] = "Example Name"
User["EmailAddress"] = "JohnDoe#example.com"
User["Username"] = "Example"
User["Password"] = "Ilovesmores12345"
User.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
println("Object has been saved.")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
When a user enters his/her information to the text fields and hit's sign up, I need for the information to save into a parse database for further use on the log in page. I feel like i'm over thinking and making it more complicated, is there a way to do this easily?
For signing up don't use user.save - use user.signUpInBackgroundWithBlock
Check this link, it's Parse iOS Guide.
My example, create a button and connect it to signUpPressed method. Here's the method.
#IBAction func signUpPressed(sender: AnyObject) {
let userName = userNameField.text
let email = emailField.text.lowercaseString
let password = passwordField.text
let fullName = fullNameField.text
var user = PFUser()
user.username = userName
user.email = email
user.password = password
//for custom fields use default key-value assign
user["fullName"] = fullName
user.signUpInBackgroundWithBlock{ (succeeded: Bool, error: NSError?) -> Void in
if let error = error {
let errorString = error.userInfo?["error"] as? String
// Show the errorString somewhere and let the user try again.
} else {
// Hooray! Let them use the app now.
}
}
}
And I'd recommend to name your object's fields starting with lowercase letter, so that it can't be confused with class names.

Array appending not working across files in swift

Im currently implementing a like functionality in my app, and I can't seem to be able to get this append and retrieving to work. Here is my Button Action which is found in my ViewController file
var Liked = Favourite()
let factBook = FactBook()
#IBAction func favour() {
var currentQuote = factBook.factsArray[factIndex]
Liked.favouriteArray.append(currentQuote)
}
The Favourite struct is called from
import Foundation
struct Favourite {
var favouriteArray: [String] = []
}
(The factBook struct is the same thing except the array actually has elements inside.)
Now my goal is to get all this to display on a separate view controller called favouriteViewController:
import UIKit
class FavouriteViewController: UIViewController {
#IBOutlet var LikeQuote: UILabel!
var liked = Favourite()
override func viewDidLoad() {
super.viewDidLoad()
if liked.favouriteArray.count > 0 {
LikeQuote.text = liked.favouriteArray[0]
} else if liked.favouriteArray.count == 0 {
LikeQuote.text = "No Liked Quotes Found, Go Favour Some!"
}
}
Now when I hit the button, theoretically I should be able to append it to the favouriteArray and then be able to display it on my favouriteViewController file, however when I save it and then open viewcontroller file it defaults to the liked.favouriteArray.count=0 scenario and prints out the text no matter how many quotes I save. I just need an idea of what's going wrong in this process?
Update: If I put append Hello world into text it still does not append to element and evaluates the array value as 0.
The problem is that because you are not saving the data somewhere like into a database or file, you won't be able to retrieve it so the code you add into the viewDidLoad will not work The only way for it to work is when the UIButton was tapped check the code below. Hope that Helps
import Foundation
import UIKit
struct Favourite {
var favouriteArray = [String]()
}
class FavouriteViewController: UIViewController {
// let factBook = FactBook()
#IBOutlet var LikeQuote: UILabel!
var liked = Favourite()
override func viewDidLoad() {
super.viewDidLoad()
}
func updateContent(){
if liked.favouriteArray.count > 0 {
LikeQuote.text = liked.favouriteArray[0]
}
else if liked.favouriteArray.count == 0 {
LikeQuote.text = "No Liked Quotes Found, Go Favour Some!"
}
}
#IBAction func favour() {
// var currentQuote = liked.factsArray[factIndex]
// Liked.favouriteArray.append(currentQuote)
liked.favouriteArray.append("today is a new day ")
updateContent()
}
}

When trying to convert a UITextField text to Int Xcode 7 gives me an error

I'm new to programming and after doing some tutorials online I decided to make my own app with Xcode 7 to be able to run my app on my iPhone. But when I try to get input data from a text field and put it into a var it gives me an error. I have tried to use the following:
var initialChips = 0
var initialBlind = 0
#IBOutlet weak var txtBlind: UITextField!
#IBOutlet weak var txtChips: UITextField!
#IBOutlet weak var doneBtn: UIBarButtonItem!
#IBAction func doneBtn(sender: AnyObject) {
let initialChips:Int? = Int(txtChips.text)
let initialBlind:Int? = Int(txtBlind.text)
}
Xcode will ask to put a "!" after ".text" but after doing that it gives me a warning: "Initialization of immutable value 'initialChips' (or 'initialBlind' was never used: consider replacing with assignment to '_'or removing it".
What can I do to set a value to my var?
The thing is that the let initialChips:Int? = Int(txtChips.text) generates a new variable called initialChips (different from the variable from the class). The difference between let and var is that let is inmutable and var is not. You should do:
initialChips = Int(txtChips.text)
To assign the integer from the UITextField to your class variable rather than declaring a new inmutable variable (with the same name) and do nothing with it.
Of course, the same happens with initialBlind
EDIT:
Try the following:
#IBAction func doneBtn(sender: AnyObject) {
if let initialChips = Int(txtChips.text!) {
self.initialChips = initialChips
}else {
self.initialChips = 0
}
if let initialBind = Int(txtBind.text!) {
self.initialBind = initialBind
}else {
self.initialBind = 0
}
}
You should add the ! after the closing parenthesis, not after .text, like so:
let initialChips:Int? = Int(txtChips.text)!

Swift: Set UITextField.text from class (retrieved value from SQLite)

I am using Swift with SQLite.swift. I have the following UIViewController:
class LoginViewController: UIViewController {
#IBOutlet weak var emailField: UITextField!
func setEmailAddress(email:String){
emailField.text = email
}
override func viewDidLoad() {
MySQLite().updateLatestEmailAddressFromUserTable() // breaks here (email is in console, though...)
}
}
Then I am trying to update it's value (through the setEmailAddress function) from another class:
class MySQLite {
func updateLatestEmailAddressFromUserTable(){
let dbPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let db = Database("\(dbPath)/db.sqlite3")
let users = db["users"]
let id = Expression<Int>("id")
let email = Expression<String>("email")
let time = Expression<Int>("time")
for user in users.limit(1).order(time.desc) {
println(user[email]) // this works, correctly outputs in console: email#domain.com
LoginViewController().setEmailAddress(user[email]) // breaks here
}
}
}
above code gives me the following error
fatal error: unexpectedly found nil while unwrapping an Optional value
To explain a little further: I am retrieving the most recent entry in SQLite table to get the user's email address and update the text field in the login view controller. This allows for easier log in for returning users.
I have been struggling with this for over 2 hours now and trying various things. The main problem I believe is that when I try to simply return the email address as string from my second function and set the field directly from LoginViewController, it doesn't work (SQLite related code was not "executed" yet I believe).
possibly related thread (Obj-C):
set UITextField.text from another class
Here whats happening LoginViewController().setEmailAddress(user[email]) creates new instance of LoginViewController which is not same as your current LoginViewController.
Why don't you make protocol and define as delegate in MySQLite
And LoginViewController will have implementation of update method. Pass the delegate to MySqlite
In MySQLite when you get the value form database call the delegate update method.
Example
MySQLite
protocol loginDelegate
{
func update(NSString)
}
class MySQLite {
var delegate:loginDelegate?
func updateLatestEmailAddressFromUserTable(){
let dbPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let db = Database("\(dbPath)/db.sqlite3")
let users = db["users"]
let id = Expression<Int>("id")
let email = Expression<String>("email")
let time = Expression<Int>("time")
for user in users.limit(1).order(time.desc) {
println(user[email]) // this works, correctly outputs in console: email#domain.com
if((delegate) != nil)
{
delegate?.update("example#example.com")
}
}
}
}
class LoginViewController: UIViewController,loginDelegate {
#IBOutlet weak var emailField: UITextField!
func setEmailAddress(email:String){
emailField.text = email
}
override func viewDidLoad() {
var mySQLite: MySQLite=LoginClass();
mySQLite.delegate=self;
[mySQLite .updateLatestEmailAddressFromUserTable()];
}
func update(email: NSString) {
println(email);
emailField.text = email
}
}
Make sure that the view which has the emailField has been instantiated on the screen.
#IBOutlet weak var emailField: UITextField!
This is an optional, which will be nil until the storyboard or nib for it is loaded. I assume OnBoardingRegistrationFormController is an instance of your LoginViewController class?
I see you've accepted an answer, but in this case creating a protocol is likely overkill. If sqlite is your model, why not just have the function return a value, and then you can assign the value to the text field in the controller. ex.
class LoginViewController: UIViewController {
#IBOutlet weak var emailField: UITextField!
override func viewDidLoad() {
emailField.text = MySQLite().updateLatestEmailAddressFromUserTable()
}
}
class MySQLite {
func updateLatestEmailAddressFromUserTable() -> String{
let dbPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let db = Database("\(dbPath)/db.sqlite3")
let users = db["users"]
let id = Expression<Int>("id")
let email = Expression<String>("email")
let time = Expression<Int>("time")
for user in users.limit(1).order(time.desc) {
println(user[email]) // this works, correctly outputs in console: email#domain.com
return user[email]
}
}
}
The issue is that LoginViewController's view isn't loaded when you try to assign a text to the textField. i.e: emailField is nil and unwrapping nil values leads to a runtime crash (since the outlet has not been connected to it's storyboard/xib counterpart).

Resources