-1

import UIKit

class ViewController: UIViewController { var data : [String] = [""]

    @IBOutlet weak var firstName      : TweeActiveTextField!
    @IBOutlet weak var lastName       : TweeActiveTextField!
    @IBOutlet weak var dateOfBirth    : TweeActiveTextField!
    @IBOutlet weak var EMail          : TweeActiveTextField!
    @IBOutlet weak var mobileNumber   : TweeActiveTextField!
    @IBOutlet weak var saveButton     : UIButton!


@IBAction func saveAction(_ sender: UIButton)
      {

          let alert = UIAlertController(title:"Sucessfully Saved", message:"Your Details Are Saved", preferredStyle: UIAlertController.Style.alert)
           var OKAction = UIAlertAction(title: "ok", style: UIAlertAction.Style.default)
           {
                             (OKAction) in
                             print("Ok Button Pressed")
           }
           present(alert,animated: true,completion: nil)
           alert.addAction(OKAction)


        var name = "\(firstName.text!)" + "\(lastName.text!)"


        button = UIButton()
          button.frame = CGRect(x: 210, y: yPosition, width: 150, height: 50)
          button.setTitle(name, for: UIControl.State.normal)
          button.backgroundColor = .cyan
          button.setTitleColor(.black, for: UIControl.State.normal)


          button.addTarget(self, action: #selector(mainAction), for: UIControl.Event.touchUpInside)

          textView.addSubview(button)
        yPosition += 70

      }
    @objc func mainAction()
      {
        let defaults = UserDefaults.standard
         data += ["\(firstName.text!) = \(firstName.text!)",
          "\(lastName.text!) = \(lastName.text!)",
      "\(EMail.text!) = \(EMail.text!)",
          "\(dateOfBirth.text!) = \(dateOfBirth.text!)",
          "\(mobileNumber.text!) = \(mobileNumber.text!)"]

          defaults.set(data, forKey: "savedData")
         // defaults.removeObject(forKey:"savedData")
          print(data)
    }


      override func viewDidAppear(_: Bool)
         {
          let defaults  = UserDefaults.standard
             data = defaults.object(forKey: "savedData") as! [String]
             print(data)
         }
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

} i edited the code please check it out.in viewDidApper Function..i got thread .... Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/madhu/Downloads/SegmentNAlertTask/SegmentNAlertTask/ViewController.swift, line 139

Madhu
  • 9
  • 2
  • *I am getting error*. What error? And why do you call `super.viewDidLoad` in `viewDidAppear`? And `@IBOutlets / @IBActions` must be on the top level of the class. Actually the entire code is a mess. Please clean it up. – vadian Feb 12 '20 at 16:10
  • sorry for this(override func viewDidLoad(), super.viewDidLoad())..by copying and Pasting that line was included.. – Madhu Feb 12 '20 at 16:13

1 Answers1

1

You're getting a crash because you're retrieving a nil value from UserDefaults, or because there's something that is not a [String] or can't be typecasted into a [String].

In this snipe of code:

data = defaults.object(forKey: "savedData") as! [String]

You're retrieving an Any? object.
That is, an Optional object that can hold or not hold a value.
Plus, it's an object that can be virtually any class.

And then you're forcing it into a [String], which will obviously crash if it isn't a [String] object.

You should replace that line of code with this:

data = defaults.object(forKey: "savedData") as? [String]

That way, you'll safely unwrap the retrieved object and try to typecast it into a [String]. If it fails, your data will be nil instead of crashing the application.

You can also provide a default value if the typecast fails, like this:

data = defaults.object(forKey: "savedData") as? [String] ?? []

If the typecast fails, you'll get an empty array of [String].

TL;DR: I'd advise you to research Optionals and how to work with them.

IloneSP
  • 429
  • 2
  • 13