Vizzy Vizzy - 1 year ago 126
Swift Question

Swift – "Cannot find object class with name"

I'm a newcomer to Cocoa programming, having never got into Objective-C. Now, I am trying to learn it with Swift by going through the Aaron Hillegrass book “Cocoa Programming for Mac OS X, 4e" and implementing everything there in Swift instead of Obj-C. It has been going okay so far, but I hit a roadblock in Chapter 8 (the RaiseMan application).

Here is the Objective-C code from the book:

The header:

#import <Foundation/Foundation.h>

@interface Person : NSObject {
NSString *personName;
float expectedRaise;
@property (readwrite, copy) NSString *personName;
@property (readwrite) float expectedRaise;

And here is the implementation

#import "Person.h"

@implementation Person

@synthesize personName;
@synthesize expectedRaise;

- (id)init
self = [super init];
if (self) {
expectedRaise = 0.05;
personName = @"New Person";
return self;


You are then supposed to go to Interface Builder, get an Array Controller, specify Person as its class, and add personName and expectedRaise as its keys.

I rewrote the Person class in Swift as follows:

import Cocoa

class Person: NSObject {
var personName = String()
var expectedRaise = Float()

and connected it to the ArrayController as the book told me to.

There is also some code in the Document file:

init() {
employees = NSMutableArray()
// Add your subclass-specific initialization here.
var p = Person()
p.personName = "New Person"
p.expectedRaise = 0.05

Here is what the interface looks like (SO won't let me post it directly)

When I try to run the app and click the "add employees" button, I get this error in the console:

"RaiseMan[9290:303] Cannot find object class with name Person"

So, my question is: what am I doing wrong?

Answer Source

Short answer: you need to specify the class namespace (module name) in Interface Builder: RaiseMan.Person

Details and other options:

This is because Swift adds a prefix to the name of every class injected into the Objective-C runtime in order to avoid name collisions. The prefix follows this convention: _TtC$$AppName%%ClassName, where $$ is the length of AppName and %% is the length of ClassName (see this other SO question for more info).

So in order for the array controller to be able to instantiate the Person class, you need to provide the mangled name in Interface Builder: _TtC8RaiseMan6Person.

Another option is to provide an explicit Objective-C name for your Swift class by using the @objc(<#name#>) attribute:

class Person: NSObject {

In that case, you can provide the name specified in your @objc attribute to Interface Builder (e.g. Person). See the Using Swift with Cocoa and Objective-C guide for more details.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download