3

I have an XCode Project which I was developing in objective C but now with Swift I have a few classes saved as .swift files. When I am referencing these as custom classes in the Interface Builder, they don't work and I get an error that the class doesn't exist.

What am I missing in terms of bridging the gap between the two? I have the header file to make the objective C available to Swift but not sure about the other way around

Thanks

2014-07-08 20:18:07.463 FoodForTeeth[22030:70b] Unknown class SecondViewController in Interface Builder file.
2014-07-08 20:18:07.496 FoodForTeeth[22030:70b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x8c85390> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key date.'
*** First throw call stack:
(
    0   CoreFoundation                      0x01acf5e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018528b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01b5f6a1 -[NSException raise] + 17
    3   Foundation                          0x01513c2e -[NSObject(NSKeyValueCoding) setValue:forUndefinedKey:] + 282
    4   Foundation                          0x0147ff3b _NSSetUsingKeyValueSetter + 88
    5   Foundation                          0x0147f493 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 267
    6   Foundation                          0x014e194a -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 412
    7   UIKit                               0x00866cd5 -[UIRuntimeOutletConnection connect] + 106
    8   libobjc.A.dylib                     0x018647d2 -[NSObject performSelector:] + 62
    9   CoreFoundation                      0x01acab6a -[NSArray makeObjectsPerformSelector:] + 314
    10  UIKit                               0x0086582e -[UINib instantiateWithOwner:options:] + 1417
    11  UIKit                               0x006d7c95 -[UIViewController _loadViewFromNibNamed:bundle:] + 280
    12  UIKit                               0x006d843d -[UIViewController loadView] + 302
    13  UIKit                               0x006d873e -[UIViewController loadViewIfRequired] + 78
    14  UIKit                               0x006d8c44 -[UIViewController view] + 35
    15  UIKit                               0x006f2a72 -[UINavigationController _startCustomTransition:] + 778
    16  UIKit                               0x006ff757 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
    17  UIKit                               0x00700349 -[UINavigationController __viewWillLayoutSubviews] + 57
    18  UIKit                               0x0083939d -[UILayoutContainerView layoutSubviews] + 213
    19  UIKit                               0x0062fdd7 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
    20  libobjc.A.dylib                     0x0186481f -[NSObject performSelector:withObject:] + 70
    21  QuartzCore                          0x045ab72a -[CALayer layoutSublayers] + 148
    22  QuartzCore                          0x0459f514 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    23  QuartzCore                          0x0459f380 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
    24  QuartzCore                          0x04507156 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
    25  QuartzCore                          0x045084e1 _ZN2CA11Transaction6commitEv + 393
    26  QuartzCore                          0x04508bb4 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
    27  CoreFoundation                      0x01a9753e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
    28  CoreFoundation                      0x01a9748f __CFRunLoopDoObservers + 399
    29  CoreFoundation                      0x01a753b4 __CFRunLoopRun + 1076
    30  CoreFoundation                      0x01a74b33 CFRunLoopRunSpecific + 467
    31  CoreFoundation                      0x01a7494b CFRunLoopRunInMode + 123
    32  GraphicsServices                    0x02ebc9d7 GSEventRunModal + 192
    33  GraphicsServices                    0x02ebc7fe GSEventRun + 104
    34  UIKit                               0x005c594b UIApplicationMain + 1225
    35  FoodForTeeth                        0x0001c42d main + 141
    36  libdyld.dylib                       0x02b5e701 start + 1
    37  ???                                 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)  

SecondViewController.swift

import UIkit
import CoreData

@objc(SecondViewController) class SecondViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var txtTask: UITextField!
    @IBOutlet var txtDesc: UITextField!
    @IBOutlet var date: UIDatePicker!
    @IBOutlet var dateDisplayLabel: UILabel!


    override func viewDidLoad() {
        super.viewDidLoad()

        configureDatePicker()
    }

    func configureDatePicker() {

        date.addTarget(self, action: "updateDatePickerLabel", forControlEvents: .ValueChanged)

        updateDatePickerLabel()
    }

    func updateDatePickerLabel() {
        dateDisplayLabel.text = dateFormatter.stringFromDate(date.date)
    }

    @lazy var dateFormatter: NSDateFormatter = {
        let dateFormatter = NSDateFormatter()

        dateFormatter.timeStyle = .ShortStyle

        return dateFormatter
        }()


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    //Events
    @IBAction func btnAddTask_Click(sender: UIButton){

        let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
        let context:NSManagedObjectContext = appDel.managedObjectContext

        let ent = NSEntityDescription.entityForName("Food", inManagedObjectContext: context)

        var newFood = food(entity: ent, insertIntoManagedObjectContext: context)
        newFood.foodname = txtTask.text
        newFood.date = dateFormatter.stringFromDate(date.date)

        context.save(nil)


      /*
        taskMgr.addTask(txtTask.text, desc: dateFormatter.stringFromDate(date.date));

        self.view.endEditing(true)


        txtTask.text = ""
        //txtDesc.text = ""
        //self.tabBarController.selectedIndex = 0;*/

        self.navigationController.popViewControllerAnimated(true)

    }

    //iOS touch functions
    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!){
        self.view.endEditing(true)
    }


    func textFieldShouldReturn(textField: UITextField!) -> Bool {
        textField.resignFirstResponder();
        return true
    }

}
Prateek
  • 1,724
  • 3
  • 15
  • 27
  • Swift class names get mangled (the module name gets added to the class name, among other things) which makes them hard to reference in Interface Builder. Make sure that the Module is set correctly in the "Custom Class" block of the item properties in Interface Builder. – David Berry Jul 08 '14 at 19:01
  • Thanks for that. I've checked that and it matches up. If you look below, those problems still persist which are in the comments :/ – Prateek Jul 08 '14 at 19:14
  • You can also try using `@objc(MyClassName) class MyClassName` to get around the name mangling. You might also post the exact error message your seeing as that might clarify the issue. – David Berry Jul 08 '14 at 19:16
  • I've already tried that :/ I've attached the error message above. Could you just run through the things I should have done from scratch (assuming I haven't done ANY bridging whatsoever) so that I can check I've done everything. – Prateek Jul 08 '14 at 19:21
  • Edit your message to add the exact error message (copy and paste the whole line or lines) the exact text matters. Among other things, it tells you WHAT class name it's looking for and not finding. – David Berry Jul 08 '14 at 19:23
  • Hi, Sorry for the delay. Added it. There are two classes that are having this problem - SecondViewController and FirstViewController (these are the only 2 swift classes I am using on the IB) – Prateek Jul 08 '14 at 19:27
  • Add the declaration for SecondViewController. – David Berry Jul 08 '14 at 19:28
  • Done that - just added the file for you to see (it's a little messy as I was following a tutorial) – Prateek Jul 08 '14 at 19:32
  • 1
    When I try to add '#import "SecondViewController-Swift.h' to the any .m file, it always says that the file doesn't exist :s – Prateek Jul 08 '14 at 19:35

1 Answers1

0

You need to read https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html


To import Swift code into Objective-C from the same target Import the Swift code from that target into any Objective-C .m file within that target using this syntax, and substituting the appropriate name:

#import "ProductModuleName-Swift.h"

Any Swift files in your target will be visible in Objective-C .m files containing this import statement. For information on using Swift from Objective-C code, see Using Swift from Objective-C.

Jack
  • 16,677
  • 8
  • 47
  • 51
  • Thanks for the quick reply. I had a look at this and I don't have the 'Define Module' option or 'Product Module Name' options in build settings. Also, the Swift classes are being used directly on the IB, so to make them available can I import them in to app delegate? – Prateek Jul 08 '14 at 18:34
  • Hmm..try that...but I don't think you should have to do anything to make them visible to IB. It should just work... – Jack Jul 08 '14 at 18:36
  • What about the missing parts in the build settings? – Prateek Jul 08 '14 at 18:57