3

I'm creating a temperature converter. When I run the application; enter a temperature, select which conversion and click convert. An error comes up. THE ERROR IS: EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode=0x0)

This is my code for ViewController:

import UIKit

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {

@IBOutlet weak var orginalValue: UITextField!

@IBOutlet weak var convertFrom: UIPickerView!
let pickerData = ["Celsius", "Fahrenheit"]

override func viewDidLoad() {
    super.viewDidLoad()
    convertFrom.dataSource = self
    convertFrom.delegate = self
}

@IBOutlet weak var labelConvertFrom: UILabel!

@IBOutlet weak var convertTo: UIPickerView!

@IBOutlet weak var labelConverTo: UILabel!

@IBOutlet weak var answer: UILabel!

@IBAction func convertButton(sender: AnyObject) {
    let a = Double(orginalValue.text!)
    let tempConvertM = TempConvert(temp: a!)
    answer.text = String(tempConvertM.convert())

}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return pickerData.count
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return pickerData[row]
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    labelConvertFrom.text = pickerData[row]
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

Here is where I'm getting the error. TempConverterModel.swift

 import Foundation

 extension ViewController{
 class TempConvert{

    var temp:Double
    var view = ViewController()

    init (temp:Double){
        self.temp = temp
    }

    func convert()->Double{
        if(view.labelConvertFrom.text == "Celsius"){ -->ERROR IS HIGHLIGHTED HERE <--
           view.labelConverTo.text = "Fahrenheit"
           return (temp-32)/1.8000; //fahrenheit formula
        }
        else{
            view.labelConverTo.text = "Celsius"
            return (temp*1.8000)+32; //celsius formula
        }

    }
}
}

I don't know what I'm doing wrong. I want to check the text in labelConvertFrom and check if it equals to "Celsius". IF it does not then return answer.

I would really appreciate anyones help. Thank you!

Marcella Ruiz
  • 323
  • 1
  • 3
  • 15

2 Answers2

2

The problem broadly stems from this line in class TempConvert:

var view = ViewController()

Here you are initializing an empty view controller. The outlets you've defined such as labelConvertFrom are not hooked up to anything, so when you try to deference them here:

view.labelConvertFrom.*text

you crash (specifically, you crash where I put the * character). The reason you crash is because at that point, labelConvertFrom is nil.

To get this to work right, you'll need to initialize the ViewController using the initWithNibName:bundle: method, passing the correct nib filename and bundle id (which is probably just NSBundle.mainBundle()).

Doing this will allow your outlets to be hooked up properly and then they won't be nil when you try to use them.

par
  • 17,361
  • 4
  • 65
  • 80
  • My apologies. I'm new to Swift and this is my first app with iOS I don't quite understand. How do I initialize the ViewController? Would I do that in the ViewController class or TempCovert? – Marcella Ruiz Nov 18 '15 at 05:24
  • `let viewController = UIViewController(nibName: "mynibfile.xib", bundle: NSBundle.mainBundle())` ... of course replace the nibName parameter with the actual name of your nib file. – par Nov 18 '15 at 05:26
  • You can do it in the `TempConvert`class. And another side note, it doesn't matter entirely in terms of it working, but the `TempConvert` class shoudn't be an extension class of `UIViewController`. Just put it in its own file `TempConvert.swift` and remove the enclosing `extension UIViewController {}` – par Nov 18 '15 at 05:28
  • Does this mean I have to create a nib file? I don't see any of my files with .xib – Marcella Ruiz Nov 18 '15 at 05:38
  • I really appreciate your help Par. – Marcella Ruiz Nov 18 '15 at 05:38
  • Yes, you will need a nib file or a storyboard. Start with a new Swift project in Xcode and the ViewController will be already setup for you. Move your code into it and it should start working. Alternately you could set every field up programmatically (manually), but I don't recommend that if you're just starting out. – par Nov 18 '15 at 05:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95404/discussion-between-marcella-ruiz-and-par). – Marcella Ruiz Nov 18 '15 at 05:46
2

As par pointed out, you should be removing the enclosing extension ViewController { } and have your TempConvert as a separate class.

Also, instead of trying to access the ViewController's instance variables in TempConvert, you should be doing the comparisons in your convertButton() method in ViewController class itself and call the appropriate conversion method in TempConvert class.

A better approach is to have a stored property for "Celsius" and a computed property for "Fahrenheit" within your ViewController class. You can refer this link for Properties in Swift language

Community
  • 1
  • 1
R P
  • 1,173
  • 2
  • 11
  • 20