NSUser defaults not saving correctly? - ios

So recently I have been making a practice app that has a textfield and a label. When you enter something into the textfield and hit save it should change the label to that text and save it. The reason why it saves is so when you open the app the text of the label is equal to the last thing you saved. The text will save again if you hit save on a new string in the text box.
The problem I am having is that the label won't appear with text until you save something new and the string isn't saving so their is nothing there even if you saved something.
Here is my code from the ViewController.swift:
//
// ViewController.swift
// Help
//
// Created by Lucas on 9/30/15.
// Copyright (c) 2015 Lucas. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
var current = ""
var Saved = ""
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
Savedlbl.text = Saved
if(currentDefault.valueForKey("Saved") != nil)
{
self.Saved = currentDefault.valueForKey("Saved") as! NSString! as String
}
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Set(sender: AnyObject) {
setall()
}
func setall()
{
current = Textfield.text!
Label.text = Textfield.text!
let currentDefault = NSUserDefaults.standardUserDefaults()
Saved = (currentDefault.valueForKey("saved") as? String)!
currentDefault.setValue(Saved, forKey: "saved")
Savedlbl.text = Textfield.text
currentDefault.synchronize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Here is where I think the problem is in the view did load that would make sense. When the app loads its not setting it to the last thing saved.
import UIKit
class ViewController: UIViewController {
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
var current = ""
var Saved = ""
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
Savedlbl.text = Saved
if(currentDefault.valueForKey("Saved") != nil)
{
self.Saved = currentDefault.valueForKey("Saved") as! NSString! as String
}
// Do any additional setup after loading the view, typically from a nib.
}
Thanks and let me know if you need any more info, I will provide it as fast as I can!

Don't use valueForKey/setValue:forKey:. Those are KVC methods. You want setObject:forKey: and objectForKey:.

Your problems are that you are doing things in the wrong order. In viewDidLoad you are setting the textfield before you have retrieved the value from user defaults and in setall you are re-saving the previously saved value, not the new value.
Try:
import UIKit
class ViewController: UIViewController {
var saved=""
var current=""
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
self.saved=currentDefault.stringForKey("Saved") ?? ""
self.Savedlbl.text=self.saved
}
#IBAction func Set(sender: AnyObject) {
setall()
}
func setall() {
self.current = self.Textfield.text!
self.Label.text = self.current
let currentDefault = NSUserDefaults.standardUserDefaults()
currentDefault.setObject(self.current,forKey:"Saved")
self.Savedlbl.text = self.Textfield.text
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Also, by convention variables should start with a lower case letter and classes with an upper case. I changed Saved to saved and Current to current but I didn't change the IBOutlets because you will need to remake the connection in IB for those, but you should.

Related

Thread 1 : 1.1 breakpoint on Xcode

i try to create my first application on Xcode ,first I tried only to overwrite the text of a label at same moment when it is write in a TextField.
Now I try just for fun , to set hidden a second label (Label2) from Utility area and with the button ok to keep these unhide but the I'll give error (Thread 1 :breakpoint 1.1).
After I try solve the problem, I think to save the text in a var String and when I press the "ok" button , it set the Label2.text=String.
Anyway ,When I build and run this code it give the same ERROR .
Anyone can help me ?
thanks
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var labelTitle: UILabel!;
#IBOutlet weak var labelRes: UILabel!;
#IBOutlet weak var textReceveirer: UITextField!;
var myString : String = " "
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func button(_ sender: UIButton) {
myString=textReceveirer.text!
labelRes.text = "hello \(myString)"
}
}
Try with the following code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var labelOne: UILabel!;
#IBOutlet weak var textReciver: UITextField!;
override func viewDidLoad() {
super.viewDidLoad()
labelOne.text = " "
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func button(_ sender: UIButton) {
labelOne.text = textReciver.text
}
}
I think the error is at line
var String=""
String is data type ,
if you want to create variable type of string you may use follow this
var myVariable : String = ""
write in your code var String=""that replace with
var Variable : String = ""
or check that connection inspector..

Count words in a string filled by user

As the title says, I want to count the words in a string, which is filled by the user. For that purpose, I will simplify it a little and I will count the white spaces in the string, store the value in an other variable and the print that new variable.
The code I am using is the following:
import UIKit
class TransViewController: UIViewController {
#IBOutlet var trad_text: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
trad_text!.layer.borderWidth = 1
trad_text!.layer.cornerRadius = 20
trad_text!.layer.borderColor = UIColor(red:0.22, green:0.26, blue:0.39, alpha:1.0).cgColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
let text = trad_text.text
let num_words = text?.characters.split(separator: " ").map(String.init)
print(num_words)
// Dispose of any resources that can be recreated.
}
But it does not print any number of words. Can someone find why this code gives the error?
Thank you for your time
You can use this code:
var string = "first second third"
let count = string.components(separatedBy: .whitespaces).count
Count equal 3 for this case.
I finally did it with the following code, maybe it will be useful to someone:
import UIKit
import Foundation
class TransViewController: UIViewController {
final class Shared {
static let shared = Shared() //lazy init, and it only runs once
var stringValue : String!
var num_words : Int!
var boolValue : Bool!
}
#IBOutlet var trad_text: UITextView!
#IBOutlet var buttonTrad: UIButton!
#IBOutlet var labelsitoh: UILabel!
#IBAction func butCalc(_ sender: AnyObject) {
let text = trad_text.text
let num_words = (text?.components(separatedBy: " ").count)!-1
Shared.shared.num_words = num_words
}
override func viewDidLoad() {
super.viewDidLoad()
trad_text!.layer.borderWidth = 1
trad_text!.layer.cornerRadius = 20
trad_text!.layer.borderColor = UIColor(red:0.22, green:0.26, blue:0.39, alpha:1.0).cgColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

How to get integer values from text fields in Swift?

I want to create a simple BMI calculator using height and weight and I am having trouble converting my UITextField strings to integers for the calculation.
Here's my working code:
import UIKit
class BMICalculator: UIViewController {
//MARK: Properties
#IBOutlet weak var weightField: UITextField!
#IBOutlet weak var heightField: UITextField!
#IBOutlet weak var solutionTextField: UILabel!
#IBAction func calcButton(_ sender: AnyObject) {
let weightInt = Int(weightField)
let heightInt = Int(heightField)
solutionTextField.text = weightInt/(heightInt*heightInt)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Anyone have any ideas? I tried searching for the solution but couldn't find anything specific to this issue.
Use this:
guard let text1 = weightField.text else {
return
}
guard let text2 = heightField.text else {
return
}
guard let weightInt = Int(text1) else {
return
}
guard let heightInt = Int(text2) else {
return
}
solutionTextField.text = weightInt /(heightInt*heightInt)
//Change your name for this outlet 'solutionTextField' to 'solutionLabel' since it is a UILabel not UITextField
The TextField only accepts a String, it wont take an Int.
Change this:
solutionTextField.text = weightInt/(heightInt*heightInt)
To this:
solutionTextField.text = String(weightInt/(heightInt*heightInt))
I don't think your code is working. To get the values out of your UITextFields and convert them to Ints, you'll need to pull them out of the '.text properties. Then, when you calculate the result, you'll need to convert it back to a string and set solutionTextField?.text equal to that result.
class BMICalculator: UIViewController {
//MARK: Properties
#IBOutlet weak var weightField: UITextField!
#IBOutlet weak var heightField: UITextField!
#IBOutlet weak var solutionTextField: UILabel!
#IBAction func calcButton(_ sender: AnyObject) {
let weightInt = Int((weightField?.text!)!)
let heightInt = Int((heightField?.text!)!)
let solution = weightInt!/(heightInt!*heightInt!)
solutionTextField?.text = "\(solution)"
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Keep in mind that this code is very dangerous because you're not safely unwrapping optionals, but that's a different thread.
Hope this helps.

Swift - UITextField resets but UILabel doesn't

I've done plenty of searching but am not finding the answer to my question.
My two UITextFields fields are resetting using the clear function. The UILabel retains the original value from the printWatts function, doesn't clear. Would appreciate any advice to resolve this small issue as I learn Swift. Thanks!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var inputFeet: UITextField!
#IBOutlet weak var inputWatts: UITextField!
#IBOutlet weak var resultsLabel: UILabel!
var stripFeet = ""
var wattValue = ""
var totalWatts : Float = 0.0
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func submitButton(sender: AnyObject) {
calculateWatts()
}
#IBAction func clearButton(sender: AnyObject) {
clear()
}
func calculateWatts() {
if let stripFeet = inputFeet.text,
wattValue = inputWatts.text,
fstripFeet = Float(stripFeet),
fwattValue = Float(wattValue){
totalWatts = fstripFeet * fwattValue
}
printWatts()
}
func printWatts() {
let formatWatts = String(format: "%0.2f", totalWatts)
resultsLabel.text = "Total watts: \(formatWatts)"
}
func clear(){
inputFeet.text = ""
inputWatts.text = ""
self.resultsLabel.text = ""
}
}
Thanks to #Eendje for suggesting that I check my connections. I had the submit and clear actions both connected to my submit button. Option drag is too convenient. All good now.

Segue between 2 view controllers (modal) via UIButton crash in Xcode 6 and Swift

so I am practicing iOs programming and I can't seem to find a solution to my problem. I have a "loginViewController" where I want my UIButton "Creer un compte" to modally present my "register" view controller. Here is the issue, when I fire up the simulator and I click the button, it crashes and bring me to the first line of AppDelegate,
"class AppDelegate: UIResponder, UIApplicationDelegate, Thread1 signal SIGABRT."
I did the segue by control dragging my UIButton to the Register view controller.
Here is the code:
import UIKit
class LoginViewController: UIViewController {
#IBOutlet weak var LoginScreenImage: UIImageView!
#IBOutlet weak var codeTextField: UITextField!
#IBOutlet weak var nipTextField: UITextField!
#IBAction func showRegisterPage(sender: AnyObject) {
let registerViewController = self.storyboard?.instantiateViewControllerWithIdentifier("RegisterViewController") as RegisterViewController
self.showViewController(registerViewController, sender: self)
}
let client = Client.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
LoginScreenImage.image = UIImage(named: "UQAMLOGO")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func connect() {
let code = codeTextField.text
let nip = nipTextField.text
if code != nil && nip != nil {
client.login(code, password: nip, callback: { (response) in
if let response = response {
if response.status == LoginStatus.Ok {
// Good login.
let homeViewController = self.storyboard!.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewController
self.showViewController(homeViewController, sender: self)
}
} else {
// Error
}
})
}
}
}
and the RegisterViewController:
import UIKit
class RegisterViewController: UIViewController {
#IBOutlet weak var firstNameTextField: UITextField!
#IBOutlet weak var lastNameTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
let client = Client.sharedInstance
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 register() {
let firstName = firstNameTextField.text
let lastName = lastNameTextField.text
let email = emailTextField.text
let password = passwordTextField.text
if(firstName != nil && lastName != nil && email != nil && password != nil){
client.register(email, password: password, firstName: firstName, lastName: lastName, callback: {(response) in
if let response = response{
if response.status == RegisterStatus.Ok{
let loginViewController = self.storyboard!.instantiateViewControllerWithIdentifier("LoginViewController") as LoginViewController
self.showViewController(loginViewController, sender: self)
}
}else{
//erreur
}
})
}
}
}
I tried to do it programatically, tried to reset the viewControllers to their default class (UIViewController).
Thanks for the help everyone,
Charles
When you make a segue from a button to another controller, the segue is performed without any code needed -- you should delete the showRegisterPage method. I'm not sure if that's your only problem, but you should delete that method, and see if you still get the error.

Resources