I am very new to swift, but i can work with javascript and php so thought this would make sense to me. I have read so many posts on this topic but non really explain mine. I have the following code which is pretty straight forward. I have several text fields with login information to pass on to php. But when i try to use the var from a function it is not possible. So i figured that out but when i try to redefine the vars outside of the function with different var i am still keep getting the error. This is the code so far
import UIKit
class RegisterPage: UIViewController, UITextFieldDelegate{
#IBOutlet weak var userEmailTextField: UITextField!
#IBOutlet weak var userPasswordTextField: UITextField!
#IBOutlet weak var userPasswordConfirmTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func registerTapped(sender: AnyObject) {
let userEmail = userEmailTextField.text
let userPassword = userPasswordTextField.text
let userConfirmPassword = userPasswordConfirmTextField.text
// check for empty fields
if(userEmail.isEmpty || userPassword.isEmpty || userConfirmPassword.isEmpty)
{
// Display alert message
displayMyAlertMessage("Alle velden gelieve invullen");
return;
}
//Check if passwords match
if(userPassword != userConfirmPassword){
// Display alert message
displayMyAlertMessage("Wachtwoorden komen niet overeen");
return;
}
}// end of registerTapped button
// send data to server side
static var urlConn: NSURL = NSURL(string: "http://xxxxxxxxx")!
var request: NSMutableURLRequest = NSMutableURLRequest(URL:urlConn);
var credLogin = "email=\(userEmail)&password=\(userPassword)"
the following line is giving the unresolved identifier error
var credLogin = "email=\(userEmail)&password=\(userPassword)"
i have tried so many different things, but i can't move the var in the function outside of it, and i have had also in other code blocks errors like this, i really would like to know how this works in swift.
Thanks
The variables userEmail and userPassword are declared within the scope of the registerTapped method. They are not visible outside this method.
Either put the line
var credLogin = "email=\(userEmail)&password=\(userPassword)"
in the method or declare the variables as instance variables right after IBOutlet declarations.
The code to send data to server side must be also executed within a method.
Related
This question already has answers here:
How to initialize properties that depend on each other
(4 answers)
Closed 5 years ago.
I'm getting this error: "Cannot use instance member 'server' within property initializer; property initializers run before 'self's available" in this line of my code
EDIT
import UIKit
import ChinoOSXLibrary
class LoginCL: UIViewController {
#IBOutlet weak var emailField: UITextField!
#IBOutlet weak var passField: UITextField!
var loggedUser: LoggedUser!
var customerId = "xxx"
var customerKey = "xxx"
var server = "https://api.test.chino.io/v1"
var chino = ChinoAPI.init(hostUrl: server, customerId: customerId, customerKey: customerKey)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
how i can solve it? The error is at this line
var chino = ChinoAPI.init(hostUrl: server, customerId: customerId, customerKey: customerKey)
You cannot use an instance of your view controller and properties until the initialization, so you just need to move your ChinoAPI initialization toviewDidLoad:
var chino: ChinoAPI!
override func viewDidLoad() {
super.viewDidLoad()
chino = ChinoAPI(hostUrl: server, customerId: customerId, customerKey: customerKey)
}
Another option is to move all hardcoded values from your view controller to ChinoAPI, but I'm not sure if it will fit your logic well.
Also, you can just move the values to init like:
ChinoAPI.init(hostUrl: "https://api.test.chino.io/v1", customerId: "xxx", customerKey: "xxx")
You need to use self after view controller init method. You can init your var chino in viewDidLoad or need to use hardcodet string if you need to init it before init view controller init method
Image of my view controller:
This is my code
class AddViewController: UIViewController {
#IBOutlet weak var questionField: UITextField!
#IBOutlet weak var correctAnswer: UITextField!
#IBOutlet weak var optionA: UITextField!
#IBOutlet weak var optionB: UITextField!
var ref: FIRDatabaseReference?
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboard()
}
#IBAction func createQuestion(_ sender: Any) {
ref = FIRDatabase.database().reference(fromURL: "https://******.firebaseio.com/")
if questionField.text != "" && correctAnswer.text != "" && optionA.text != "" && optionB.text != ""
{
self.ref?.child("Questions").setValue(["Question": questionField.text, "CorrectAnswer": correctAnswer.text, "OptionA": optionA.text, "OptionB": optionB.text])
questionField.text = ""
correctAnswer.text = ""
optionA.text = ""
optionB.text = ""
}
else
{
print("Missing fields")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is my goal in Firebase JSON:
My code is working but it replaces(ofc). Is my approach correct in saving questions so that in retrieving it will be easy? Could you give me idea how to save my questions?
First of all you must be using a pretty old version of Firebase if you are creating a database reference like that. For a while now (almost 6 months?) the correct way to create a reference to your database is
var ref: FIRDatabaseReference!
override func viewDidLoad(){
super.viewDidLoad()
ref = FIRDatabase.database().reference()
}
And in order for this to work you must download the GoogleService-info.plist file for your firebase project and add it to your Xcode project.
As far as your database structure goes...
What you have in your code is not going to produce what you are aiming for in the picture above. What you have in your code will produce this...
In order to produce data structured in the way you have pictured above you need to do this...
ref.child("Questions").child("Question1").setValue(["Question":questionField.text, "CorrectAnswer": correctAnswer.text, "optionA": optionA.text, "optionB": optionB.text])
then for question 2...
ref.child("Questions").child("Question2").setValue(["Question":questionField.text, "CorrectAnswer": correctAnswer.text, "optionA": optionA.text, "optionB": optionB.text])
and then your JSON will look like this ...
Note that I had to add the "Question" key as a child value under the "Question1" node in order to set the text for that question as its value.
Furthermore, if you are not able to increment Question1 followed by Question2... and so on, then you can use Firebase's method .childByAutoId like this for every question and Firebase will automatically generate a unique child id for that node...
ref.child("Questions").childByAutoId().setValue(["Question":questionField.text, "CorrectAnswer": correctAnswer.text, "optionA": optionA.text, "optionB": optionB.text])
the result will look similar to this...
Hope this helps, let me know if you have further questions
Since setValue() will override the whole content of Questions node.
U should create a child before upload the question to firebase.
ref.child("Questions").childByAutoId().setValue(...)
Overview
I need to save several TextFields into CoreData, but only the first one (Seen as pickerView below) saves and prints correctly. The others do not save correctly, for instance, when I try to save the integer ones, I get an error saying that they cannot take a String, which makes sense. I just cannot find a way to fix the integer-string issue. The other error occurs when I attempted to cast everything as a string ( mainly because I won't need to do any arithmetic on it, so it doesn't matter ), and it just gives me a breaking point in the saveButton function.
What I would like to know
What I ultimately need is the ability to save all of these TextFields into CoreData so that I can later retrieve them. I appreciate the help in advance. Thank you!
NOTE
I am including the entire ( or most of ) the ViewController.swift file so that you can see how I am declaring things and then how they are being called. The code in question is located in the saveButton action at the bottom of the code block.
CODE
#IBOutlet weak var locationOfMachine: UITextField!
#IBOutlet weak var engineHours: UITextField!
#IBOutlet weak var YOM: UITextField!
#IBOutlet weak var serialNo: UITextField!
#IBOutlet weak var modelName: UITextField!
#IBOutlet weak var pickerTextField: UITextField!
var pickOption = ["Wirtgen","Kleeman","Hamm","Vögele"]
override func viewDidLoad() {
super.viewDidLoad()
var pickerView = UIPickerView()
pickerView.delegate = self
pickerTextField.inputView = pickerView
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
#IBAction func saveButton(sender: AnyObject)
{
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
var entity1 = NSEntityDescription.insertNewObjectForEntityForName("UsedInfo", inManagedObjectContext:context) as NSManagedObject
entity1.setValue(pickerTextField.text, forKey: "product")
entity1.setValue(modelName.text, forKey:"modelName")
entity1.setValue(serialNo.text, forKey:"serialNo")
entity1.setValue(Int(YOM.text!), forKey:"yom")
entity1.setValue(engineHours.text, forKey:"engineHours")
entity1.setValue(locationOfMachine.text, forKey:"location")
print(entity1.valueForKey("product"))
print(entity1.valueForKey("modelName"))
print(entity1.valueForKey("serialNo"))
print(entity1.valueForKey("yom"))
print(entity1.valueForKey("engineHours"))
do {
try context.save()
}
catch {
print("error")
}
}
EDIT
Upon trying to save everything as just a string, since i only need to retrieve it, I run into this issue:
entity1.setValue(pickerTextField.text, forKey: "product")
entity1.setValue(modelName.text, forKey:"modelName")
entity1.setValue(serialNo.text, forKey:"serialNo") <-Thread1:Breakpoint1.1
entity1.setValue(YOM.text, forKey:"yom")
entity1.setValue(engineHours.text, forKey:"engineHours")
entity1.setValue(locationOfMachine.text, forKey:"location")
print(entity1.valueForKey("product"))
print(entity1.valueForKey("modelName"))
print(entity1.valueForKey("serialNo"))
print(entity1.valueForKey("yom"))
print(entity1.valueForKey("engineHours"))
I also get "(lldb)" in the debugger window.
I'll just show you how to get int from string. Use it accordingly:
var aString = "0000" // var aString = textField.text!
var numFromString = Int(aString)
You can assign the text field to aString and convert it to Int like i showed you.
For things that don't need arithmetic, define them as strings in Core Data. For other numbers, it should work to do as you have with Int(YOM.text!).
However, I suggest that you create a managed object subclass for "UsedInfo" so that you can work directly with its properties instead of using setValue:forKey:. The benefit of a subclass is that it will show you data types explicitly.
Validate all textfields before trying to store,set the appropriate keyboard for each textfield and provide the valid character set for each textfield.
For Example:
YOM text field : Use Keyboard with only integers.
Valid character set are 0 to 9
And validation for min and max if applicable.
If any of the validation criteria fails ,throw an alert to input valid data.
I guess this solves your issue.
Im making a basic registration form, and I'm getting multiple "Expected Expression in list of Expression Errors," as well as a couple expected separator errors. Ive tried fixing the errors myself, but I'm new at Swift, and wasn't able to fix it. Any help is appreciated.
import UIKit
class RegisterPageViewController: UIViewController {
#IBOutlet weak var userFullNameTextField: UITextField!
#IBOutlet weak var userEmailTextField: UITextField!
#IBOutlet weak var userPasswordTextField: UITextField!
#IBOutlet weak var userRepeatPasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func RegisterButtonTapped(sender: AnyObject) {
let userFullName = userFullNameTextField.text
let userEmail = userEmailTextField.text
let userPassword = userPasswordTextField.text
let userRepeatPassword = userRepeatPasswordTextField.text
}
// Check for empty fields
**//ERROR HERE EXPECTED DECLARATION**
if (((userFullName.isEmpty || userEmail.isEmpty || userPassword.isEmpty || userRepeatPassword.isEmpty))
{
// Display alert message
displayMyAlertMessage("All fields are required")
return;
}
// Check if passwords match
if(userPassword != userRepeatPassword)
{
// Display alert message
displayMyAlertMessage("Passwords do not match")
return;
}
func displayAlertMessage(userMessage:string)
{
var myAlert = UIAlertController(title:"Alert", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert);
}
}
// Store Data
// Display alert message with confirmation
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Error 1: Non-closed parantheses
You're missing a closing paranthesis in the first if statement of the RegisterButtonTapped function:
if (((userFullName!.isEmpty || userEmail!.isEmpty
|| userPassword!.isEmpty || userRepeatPassword.isEmpty)) {
// Display alert message
displayMyAlertMessage("All fields are required")
return
}
Three left pranthesis ((( finished by only two right ones )). I this case, you really need no set of parantheses at all, but could save one set for readability:
if (userFullName!.isEmpty || userEmail!.isEmpty
|| userPassword!.isEmpty || userRepeatPassword.isEmpty) {
// Display alert message
displayMyAlertMessage("All fields are required")
return
}
Error 2: trying to include a function declaration within another function
(As pointed out by Duy Tran)
The function displayAlertMessage(...) is positioned within the function RegisterButtonTapped. Functions may only exists as methods directly in a class/structure etc (or as a global non-class owned function e.g. in a playground).
Hence, you should make sure the function displayAlertMessage(...) is placed outside the body of function RegisterButtonTapped.
General remarks
You should avoid "forced unwrappings" of optional variables. E.g. userFullName!.isEmpty will lead to a runtime exception in case the optional immutable userFullName has valuenil`. You should read up on optionals, optional binding, and so on.
Also note that you needn't put semi-colons ; after lines in Swift. However you won't get an error for doing so:
[swift-evolution] Proposal to remove semicolons
The function displayAlertMessage is placed within the IBAction body.
It should be placed outside your IBAction function.
A big n00b here :-)
I made my first app for IOS and got everything working as long as all text fields are filled. This app is a simple calculation app and I need some help making sure that the app does not close down when fields are empty.
This is my code when a simple Calculation button is pressed.
class ViewController: UIViewController {
#IBOutlet weak var panelWidthTextField: UITextField!
#IBOutlet weak var panelHightTextField: UITextField!
#IBOutlet weak var panelsWideTextField: UITextField!
#IBOutlet weak var panelsHightTextField: UITextField!
#IBOutlet weak var panelPitchTextField: UITextField!
#IBOutlet weak var resultWithLabel: UILabel!
#IBOutlet weak var resultHightLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func calculatePressButton(sender: AnyObject) {
let w = Double(panelWidthTextField.text!)
let sw = Double(panelsWideTextField.text!)
let pi = Double(panelPitchTextField.text!)
let sizew = SizeWidthModel(pw:w!,psw:sw!,ptc:pi!)
resultWithLabel.text=String(sizew.width())
let h = Double(panelHightTextField.text!)
let sh = Double(panelsHightTextField.text!)
let sizeh = SizeHightModel(ph:h!,psh:sh!,ptc:pi!)
resultHightLabel.text=String(sizeh.hight())
}
}
This is my problem.
Hope someone can point me in the right direction.
Edit:
As I am a complete n00b at this coding I need som more help understanding this. I have tried adding various solution with no luck. I am trying to get a message to pop up when user leave fields empty, because the calculation need all fields filled in.
If someone have time to guide me that would be appreciated :-)
Took me a while to figure out optionals, too, but hopefully this explanation helps:
When converting from a String (which is what panelWidthTextField.text is) to a Double, Swift doesn't know if the String is valid or not. Since it might be valid or it might not contain a valid value (is nil), then it's an optional, String?, which can contain a valid String or which can be nil. But just because it can be nil doesn't mean that you can use nil in your code.
The "!" says "use the data in this variable, even if it's nil, because I don't think it's nil." Problem is, if it IS nil, then Double(nil) would crash your app.
If let (there is also an "if var") will say "look into (unwrap) this optional value. If it works, do what's in the first set of braces (which is a let or var assignment), otherwise do what's in the second set of braces.
if let w = Double(panelWidthTextField.text!) {
// you're good to go
} else {
// give the user instructions on how to fix the error.
}
The nil coalescing operator may also help. It reads like this:
// Unwrap a and look at it. If it a isn't nil, then use it, if it is nil, then use default value b
a ?? b
If you wanted to put in a default value (like zero if you need a valid numeral), try:
var w = Double(panelWidthTextField.text!)?? 0
Simply check to see if the user has entered text. In the function, put something like this
if myTextField.text != "" {
//rest of the code
}
Hope this helps.