Could not connect the action : to target of class NSApplication - objective-c

I come from a Cocoa touch background and there's one point I'm stuck on, I'm trying to create a ViewController from scratch and connect objects in my xib to actions in my new ViewController. I changed the file's owner to my ViewController and added outlets, and the compiler seems to be happy with what I've done.
But when I run my application, the connections seem to fail with: 'Could not connect the action start: to target of class NSApplication,' but where is this NSApplication reference hiding? To the best of my knowledge my ViewController has a class of NSViewController.
ViewController : NSViewController

I changed the file's owner to my ViewController and added outlets, and the compiler seems to be happy with what I've done.
Sure, the compiler won't care -- this is a run-time error. It sounds like you're working in your MainMenu.xib file. That file is loaded by the application object. Even though you changed the type of File's Owner in the .xib, the object that's loading the .xib is still the application.
You'll probably want to create a separate .xib file for your view controller to load. You change the type of File's Owner in that file to you view controller class! hook things up to File's Owner, and it should work fine since your view controller really will be the object that's loading the file.

Related

File's owner thinking it is superclass

Something very strange is going on with my interface builder. So I created an NSWindowController subclass in Xcode, with the create XIB option enabled. I started coding, and I successfully connected to file's owner.
But, when I run my app, I get the error :
Failed to connect (workspaceControl) outlet from (NSWindowController) to (NSSegmentedControl): missing setter or instance variable
Failed to connect (workspaceField) outlet from (NSWindowController) to (NSTextField): missing setter or instance variable
Could not connect action, target class NSWindowController does not respond to -changeNumberOfWorkspaces:
I don't know why this error is showing up as I have my code set up right:
And the File's owner is set to the right class (AddController):
So why does it try to connect my views to NSWindowController instead of my subclass?
EDIT:
Where I actually use the AddController in code:
AppDelegate.h
AppDelegate.m
It's in appdelegate because it is a menubar app. (In case anyone was wondering)
Because the actual object that is instantiated in your running program is an NSWindowController, not an AddController. You've shown us that AddController is properly declared, and you've shown us that your nib's File's Owner is set to AddController; that's great, and is why you don't get a compile-time warning or error about things being wired up incorrectly. But you haven't shown us where the controller object actually gets instantiated; and examining that would presumably reveal that it hasn't been changed to AddController. So at runtime you've got an NSWindowController, in violation of what you promised to IB would be the case; and so you get runtime errors.

cocoa could not connect action

I've been fiddling with Objective-C + Cocoa and writing a fairly simple Cocoa application. Then I encountered a runtime error that has no effect on my program execution:
Could not connect the action textField: to target of class BarController
I'm experimenting with pulling some of the windows out of MainMenu.xib and loading them with separate controllers and xib files.
In one window within a new xib I've created a Text Field and linked it to an IBOutlet NSTextField (textField) in a new NSWindowController subclass. It works and I am able to use textField to update the contents of the Text Field.
I am curious why I am getting the above runtime error and I'm hoping that understanding it will clear up some of the magic around the UI construction process.
Not much magic with plain IBOutlets, really - the fun starts when using Bindings or actions sent to some yet unknown target via First Responder and the responder chain :-)
Regarding your error:
Sounds like you've connected an outlet to a target that doesn't exist in your target class?
You might have established a connection to a property in File Owner (or some other proxy object) at some point where the owner's class was e.g. MyAppDelegate.
Then you've moved the window (or other object containing the outlet) to some other .xib and now the owner's class is MyWindowController that doesn't have a property of the same name you've connected your outlet to - and voila, the runtime won't be able to establish the connection for your outlet at runtime.
Just double-check your outlets in the Interface Editor, there's probably already some kind of warning message displayed next to outlets that look fishy.
Delete or reassign them and you're done.

Files owner and nsapplication, appdelegate

In the apple docs it states that nsapplication is the file owner of the main nib. Is this just set up by the template or must the first nib to be loaded, be loaded in this way?
Also, I read through the rest of the posts about the file owner and something still confuses me. Can IBoutlets only point to objects, if the Iboutlet is a property of the nibs file owner, and the object is found within that nib? Why does the nib even need to know the class of it's owner In addition to the object? What is enabled or disable by knowing or not knowing this?
One more, where does the appdelegate fit into this picture? Can you even change the app delegate?
Thanks :-)
Xcode's application template sets up MainMenu.xib to be loaded with NSApp as its owner. This is done by the NSApplicationMain function. NSApplicationMain looks up the NSMainNibFile key in the app's Info.plist file. If it finds that key, it uses the corresponding value as the name of the nib file to load. Xcode's app template sets NSMainNibFile to MainMenu.
It doesn't have to be done that way. You can change or delete the NSMainNibFile entry in Info.plist. You could even not use NSApplicationMain. Instead you could initialize NSApp yourself (by calling [NSApplication sharedApplication]), and then create your user interface programmatically or by loading nibs, and then call [NSApp run].
The nib loader can only connect outlets to objects in the nib it's loading, or to File's Owner, First Responder, or Application. The outlet itself doesn't have to be on File's Owner; it can be on any object in the nib.
When you set the class of File's owner, Interface Builder scans your source code to find the declaration of that class. That's how it knows which outlets and actions File's Owner should have.
The app delegate is generally the top-level controller for the application. It is notified when a variety of application-level events occur. Look at the NSApplicationDelegate Protocol Reference.
In Xcode's app template, the application delegate is an object in MainMenu.xib (you can have non-user-interface objects in a nib), which is wired to File Owner's delegate outlet. You can modify the class however you want. You can even delete the object from the nib entirely. But any serious app will need an app delegate.

How to hookup a MainWindow.xib to an empty project

Beginning with XCode 4.2, when you create an empty project using XCode 4.2, a MainWindow.xib is no longer created and hooked up for you. I've found an article that describes how to do this and I've done it and it works, but if this process has taught me anything, it has shown me that I have no idea how main(), AppDelegate and the MainWindow.xib exist together.
http://www.trappers.tk/site/2011/06/16/mainwindow-xib/
Why is MainWindow.xib class updated to UIApplication?
Why is an object placed on the xib, and then AppDelegate class is selected for the class?
Why is the delegate outlet of the File Owner connected the AppDelegate object?
Why is the the window outlet of the AppDelegate to the Window?
why does - (BOOL) application:didFinishLaunchingWithOptions: need to be commented out.
I've researched around but, I'm still not 100% sure how everything is loaded up once the application starts, and why this is setup is needed just to have a MainWindow. I have a feeling though that I should probably get all these concepts down to continue to advance in iOS development.
Why is MainWindow.xib class updated to UIApplication?
At the lowest level, nib files are loaded with the method -[UINib instantiateWithOwner:options:]. The File's Owner in a nib file is a placeholder. In Xcode, it isn't a specific object yet. It will resolve to an actual object when the nib file is loaded. Its purpose is to relate, via outlets and actions, objects inside of the nib with the object that loaded the nib. The object passed as the "instantiateWithOwner:" parameter of that UINib method is what the File's Owner placeholder in Interface Builder will resolve to.
UIApplication loads the nib file specified in the info.plist and passes 'self' for the owner parameter when loading the nib file.
By setting the class name, you're just hinting to the tools so that they can suggest the set of actions and outlets you're allowed to establish.
Why is an object placed on the xib, and then AppDelegate class is selected for the class?
When you place the generic object in the xib and change its class to 'AppDelegate' you're telling Xcode to instantiate an instance of 'AppDelegate' when the file is loaded.
Why is the delegate outlet of the File Owner connected the AppDelegate object?
UIApplication has a 'delegate' that it delegates responsibility to and notifies when interesting events occur. When you make this connection, you're setting the delegate property of the application to be the instance that you specified above. From that point on, this instance will receive the delegate messages from UIApplication, like -application:didFinishLaunchingWithOptions:.
Why is the the window outlet of the AppDelegate to the Window?
Outlets are a way to refer to objects inside of a xib. They cause properties or instance variables to be set to refer to the object pointed to by the outlet. When you make this outlet, you're making it so that the app delegate instance you created above has a way to refer to the window that's also created when the xib is loaded.
why does - (BOOL) application:didFinishLaunchingWithOptions: need to be commented out.
It represents the code-focused way to do some of the same things that are happening in the xib, and if they were both present, they would be overwriting each other.
The object placed on the XIB file is the AppDelegate because it delegates all connections in the Interface Builder, meaning if you write a method that when a button is clicked it displays text, that method would be connected to either the App Delegate or the File's Owner, preferably the delegate. The File's Owner, since it is the UIApplication, connects to the delegate because it assigns that certain object to be the App Delegate. Sorry that I couldn't answer the rest of your questions, they didn't really make sense.
Hope this helps

What describes the "File's Owner" best in objective-c / cocoa Nib?

Unfortunately, the explanation of File's Owner is pretty short at the Apple docs. I know it is an proxy object. But what's really the point about that "File's Owner" object? What is it good for?
Nib files are often referred to as "freeze dried" and ready to run, and they are a great way of making your apps more modular which can reduce memory usage. Nib files can be defrosted, or loaded into memory anytime when the app needs the objects inside it.
Whenever a nib file is defrosted, it needs a pointer to the object that defrosted it. And that object is usually, the File's owner. The File's owner allows objects inside the nib file to access objects that existed before the nib file was defrosted. In a way, the File's owner acts as a bridge between newly loaded objects and old objects.
It's easier to understand the meaning of the File's Owner reference if you read about and understand the nib loading process.
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html
Cocoa's frameworks handle many nib loads automatically on your behalf, with one of Cocoa's own built-in classes serving as the controller class that manages, or "owns" the nib file's instantiated objects. When you load your own nibs manually, you get to choose which class will serve as the file's owner.
When you read about the nib loading process, pay attention to the "owner:" parameter on many of the loading methods. Its exactly this object that will be connected to the objects in your nib file as File's Owner
I know it is an proxy object.
It's not. It's a real object. The icon in the nib is a proxy only in the sense that all the other icons represent objects archived in the nib, and the File's Owner isn't. But the FO is not a proxy object in your application.
But what's really the point about that "File's Owner" object? What is it good for?
It's the object that owns the objects in the nib.
That's it. Nothing more to it than that.
Best way to explain it is with an example of how to set it up. Let's say you have an NSWindowController subclass which is a controller for a preferences window. The preferences window is in a NIB called "Preferences".
In your NSWindowController subclass you would have the following init method:
- (id)init {
if (self = [super initWithWindowNibName:#"Preferences"]) {
//do initalisation
}
return self;
}
This initialises the window controller, associating it with the nib named "Preferences" in the application's main bundle. Note that the NIB has not yet been loaded (this will happen when you first call -window on the window controller.
In the Preferences NIB you would then click on the File's Owner icon and then go to the Class Info panel of the Inspector. In here you would set the class to the name of your window controller class (eg PreferencesController). This now represents an instance of your window controller so you can connect up outlets and actions.
While editing in IB it is just a proxy of the object, as with any object you drag to the NIB, but when the NIB is loaded it will be set to the window controller you created.
http://www.cocoadev.com/index.pl?FilesOwner
In essence, whichever object loaded the NibFile becomes the file's owner for that nib file.