2

I'm near the end of translating my code from Objective-C to Swift and I started switching the view controller classes to Swift. I managed to fix most of the problems with the view controllers but I keep getting this error for one of my View controllers.

When it crashes: "Thread 1 signal sigabrt"

The error log:

Terminating app due to uncaught exception 'NSUnknownKeyException', 
reason: '[<UIViewController 0x7fd98fc65ee0> setValue:forUndefinedKey:]: 
this class is not key value coding-compliant for the key background.'

Note: "background" in this case is a UIImageView Outlet.

I been through multiple stack over flow solutions and none seem to help me. I've tried:

  • Cleaning the build folder

  • Deleting the app on the simulator

  • Deleting the derived folder

  • Checking for extra IBOutlets

  • Deleting the connections and reconnecting them

  • Renaming the outlet

  • Checking for extra connections in storyboard

  • Debugging the viewDidLoad() function

Here is my code:

IBOutlet var background: UIImageview!

override func viewDidLoad() {
    super.viewDidLoad()

    let image: UIImage = UIImage(named: UserDefaults.standard.string(forKey: "Background")!)!
    background.image = image
    ...
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
James Castrejon
  • 567
  • 6
  • 16

1 Answers1

5

The problem is revealed in the error message:

[UIViewController 0x7fd98fc65ee0> setValue:forUndefinedKey:]:

So you need to set the class of this view controller in the storyboard to the class of the real view controller that has the background property.

In all probability you had this correctly set already, but it was working in Objective-C only. If you go into the Identity inspector and delete the class, and hit return, and then enter the class again, and hit return, you'll see that now the Identity inspector sees that we are supposed to get this class from the Swift module, and things will start working in Swift.

Basically the root cause is probably Swift’s name mangling. An Objective-C class called MyClass is really called MyClass, but a Swift class called MyClass isn’t. Removing the name and reentering it shows Objective-C the class’s new name.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Actually you more likely had this right and then wrecked it somehow. I say that because if you never had it right, you would never have been able to create the outlet in the first place. – matt Jul 03 '19 at 00:07
  • Well I use to have it pointing to an Objective c version of the view controller and then tried switching it to the swift version. Maybe that's what caused the error. Anyways, I fixed it by completely removing the class from the view controller on Story Board, shifting the focus onto another view controller, returning the focus to the first view controller and adding the class again. Much appreciated. – James Castrejon Jul 03 '19 at 20:18
  • 3
    Yes, you make a very good point! I will add that to my answer. This is a special case having to do with the way classes are defined in modules. It is not right for me to say "you forgot", and I will change that. Thank you. – matt Jul 03 '19 at 20:30
  • Just a side note, this also works on custom UI classes. For example, I fixed my custom UICollectionViewCell by following your answer. – James Castrejon Jul 03 '19 at 21:21
  • The joke is that I wrote an article years ago about how to translate your app from Objective-C to Swift... https://www.oreilly.com/ideas/translating-your-objective-c-project-to-swift ... and I explained in step 9 of the step-by-step instructions that this crash would happen and what to do about it! – matt Jul 03 '19 at 22:02