Swift and InterfaceBuilder Question... can't get IB to find Swift Classes.

error message :

Cannot find object class with name BKSubProj


the Class:

class BKSubProj : NSObject{
    var name : String = "subProjectName"
    var extensions : [String:NSURL] = [:]
}


I have an array controller instantiated in the XIB file.

I have a manager class which is also instantiated in the XIB file:

class BKSubProjMan : NSObject {
   
    @IBOutlet weak var subProjectController: NSArrayController!
    @IBOutlet weak var extensions: NSArrayController!
   
     // this is thae array that the subProject controller is bound to.
    var subProjectArray : [BKSubProj] = []
   
    @IBAction func newSubProject(object: AnyObject) {
       
    }
   
    @IBAction func removeSubProject(object: AnyObject) {
       
    }
   
    @IBAction func manageInFinder(object: AnyObject) {
       
    }
}


there is a button hooked up to the subProjectArrayController's add: action.

when clicked, I get the error.


this happens often enough, that I suspect my sanity. Either it's a step I'm skipping, or it's a bug.

thoughts?

Answered by DTS Engineer in 63670022

OK, I took a shot at this myself and I got it to work. Here’s my BKSubProj class.

@objc(BKSubProj) class BKSubProj : NSObject {
    var name : String = "subProjectName" 
    var extensions : [String:NSURL] = [:] 
}

[Yes, that’s

@objc
, not
@obj
. Sorry about the bum steer there.]

I then put

BKSubProj
in the array controller’s Class field in IB. With that I was able to bind a table to the array controller, add elements to the array controller via
-add:
, and see each element in the table.

I’m not sure what’s going wrong in your specific setup but I think I’ve taken this about as far as I can in the context of DevForums. If you get completely stuck, you should open a DTS tech support incident and we can help you in a more formal context.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Have you told the array controller about the class of objects within the controller (via the Mode popup and Class field in the Attributes Inspector in IB)? In most places within Xcode you have to configure Swift classes with both a module name and a class name. See the Identity Inspector for an example. AFAICT the array controller doesn’t support that, so you may need to give it a mangled name. If that’s the case, it’s probably worth a bug against the array controller inspector.

Alternatively, as a quick check, you could add

@obj(BKSubProj)
to your BKSubProj class.

[Sorry I’m being vague here; I don’t have time to try this out right now.]

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Yes. i have indeed setup the Array controller to manage my BKSubProj class in IB (rather than the default mutableDictionary). and... I've run into the module issue before (XCode plays fast and loose with modules.) you are correct, the ArrayController object has no setting available for setting the object class's module.


I would be perfectly happy to mangle the name of my class, but that reminds me of my high school professor, who said: "mutation has the kinds of effects on people, that taking your watch putting it into a sock, and repeatedly hitting it against the wall, would have on your watch." His point: random chaos won't improve the situation. I need to know the pattern, or I'm creating random chaos.


I added this line:

@objc(BKSubProj)

to my subProj class, making no difference whatsoever.


adding instead, the suggested:

@obj(BKSubProj)

causes an error.

trying

@objc(BKSubProj) as the object calss in the array controller, had a net negative effect. same error different name.

Accepted Answer

OK, I took a shot at this myself and I got it to work. Here’s my BKSubProj class.

@objc(BKSubProj) class BKSubProj : NSObject {
    var name : String = "subProjectName" 
    var extensions : [String:NSURL] = [:] 
}

[Yes, that’s

@objc
, not
@obj
. Sorry about the bum steer there.]

I then put

BKSubProj
in the array controller’s Class field in IB. With that I was able to bind a table to the array controller, add elements to the array controller via
-add:
, and see each element in the table.

I’m not sure what’s going wrong in your specific setup but I think I’ve taken this about as far as I can in the context of DevForums. If you get completely stuck, you should open a DTS tech support incident and we can help you in a more formal context.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I would be more than happy to provide a simple example of this repeatable, unavoidable (as far as I can tell) bug. It's a 62k zip file.

if it's operator error, then it wouldn't have worked when I changed the class to NSMutableDictionary. but it did.


but I can't send it to you in this forum. can i send it to you over your email?

but doing this

@objc(BKSubProj) class BKSubProj : NSObject


worked just fine.

I ran into the same problem, with the same solution, in using an NSObject derived class and binding an Array Controller to a Table View.


So question, when do we need to add @objc(ClassName) for an NSObject derived class ?

I read in « Using Swift with Cocoa and Objective-C. » that

« When you define a Swift class that inherits from NSObject or any other Objective-C class, the class is automatically compatible with Objective-C. All of the steps in this section have already been done for you by the Swift compiler. »


It also says:

« The @objc attribute makes your Swift API available in Objective-C and the Objective-C runtime. »

Is binding calling Objective C runtime in the background (My code is pure Swift) ?

Swift and InterfaceBuilder Question... can't get IB to find Swift Classes.
 
 
Q