i am currently starting to learn Xcode and objective-c and i am reading three different books on that topic currently. All of these books refer to a file called "AppDelegate" (My_First_ProjectAppDelegate.m, My_First_ProjectAppDelegate.h) which are said to be "created with the Project" (i am creating a "Cocoa Application"). These files are not present when I create a new Project. I seem to be not the only one having this problem (see http://pragprog.com/titles/dscpq/errata ).
Is there any more information about AppDelegate? What is the current practice on how to deal with a missing Appdelegate? i am using Xcode Version 3.1.4 on Mac OSX Leopard.
AppDelegate is nothing more than a common NSObject class with needed connections in MainMenu.xib. You can easily recreate your own:
Create a class, name it AppDelegate
Open MainMenu.xib and add NSObject object to object palette
In object inspector's Identity tab (the last one) set object's class to AppDelegate (you should get autocomplete)
Ctrl+drag from Application object to your newly created AppDelegate object and choose "delegate" from opened panel.
As I recall, only the iPhone templates were providing delegate classes by default. This is not a huge deal, but I can see how you would be concerned if you are just learning. Are you sure what you are reading is relevant to MacOS applications and not Iphone?
You can always create your own delegate class manually. You just create a class as you normally do, then set it as the delegate for NSApplication in Interface Builder.
I think the confusion comes from the version of XCode you are using.
Xcode version 3.2 changed the default behavior when you create a new project: it now creates an AppDelegate for your project. I can't remember what the earlier versions did, but it was different.
As Eimantas says, if you want to use an AppDelegate then you can just create one following the steps he describes.
Related
I have studying how to use IKImageView in my app. I downloaded the following demo from Apple site.
https://developer.apple.com/library/mac/samplecode/IKImageViewDemo/Introduction/Intro.html#//apple_ref/doc/uid/DTS10004049
One thing I do not understand is: This project has only implemented a Controller class.
#interface Controller : NSObject
{
...
I do not understand how does it work at all. If I create a new project in XCode, it will usually generate an AppDelegate class which implements NSApplicationDelegate interface.
I do not know if I understand the mechanism correctly.
Does the following steps describe how it works?
1) In info.plist it specifies the main bundle is MainMenu.xib.
2) the Window is binded to the Controller like so
3) When the application starts, it loads the Windows from the MainMenu.xib and the Controller class takes over the windows interaction from there.
It's really old sample code. It predates Xcode project templates generating an app delegate for you.
Back then, early Xcode and ProjectBuilder (the old name for it)
Left it up to you to do that.
Lots of older sample code has this sort of thing. As long as things get kickstarted by nib loading, magic happens, objects are instantiated and connected
If you have a simple controller that inherits from NSObject and it has a proxy in you main nib file, it will get created. If you also connect its proxy as delegate to some view or control in the nib, all of that happens.
You don't technically need an object that is the delegate of you NSApplication object. But in reality it is a good best practice and any non trivial app will have that and a lot more.
There's a lot of magic that happens when the C function NSApplicationMain() is called at the launch of your app.
The old and in many ways out if date book Cocoa in a Nutshell covers this well.
Yeah you pretty much describe how it works and what it's doing.
It's relying on the fact that NSApplicationDelegate is an informal protocol and it doesn't declare that Controller conforms to it and is using the NIB to kick-start the app.
So according to this tutorial
"Xcode uses the product name you entered to name your project and the app. Xcode uses the class prefix name to name the classes it creates for you. For example, Xcode automatically creates an app delegate class and names it HelloWorldAppDelegate. If you enter a different value for the class prefix, then the app delegate class is named"
However when I create my project, it doesn't create the files with my project name. So instead of "ProjectNameAppDelegate.h" I just have "AppDelegate.h". Is there a reason why XCode wouldn't create the proper files I need and how do I fix it?
I also don't have a ViewController.xib file which most online tutorials say I should have. I do have a "MainStoryboard.storyboard but I'm not sure if that counts as the same thing.
The tutorial you mentioned is on an old Xcode. The latest Xcode wont create appDelegate and ViewController classes by prefixing project name as you said like ProjectNameAppDelegate.h. It simply create AppDelegate.h only. It is not a bug.
In the above figure you can see that i have selected Use StoryBoards, So Xcode wont create Xib files for your viewController instead it will create a storyboard only. Here you dont want xib . Storyboard is replacement for the xib. If you unselect that feature you will get xib back. As a beginner you should go through several tutorial that uses both xib and storyboards.
Adding to Anil's answer, Storyboard is a replacement for the old .xib files.
I am working with cocos2d and CoreData. I have imported "AppDelegate.h" but I can't create an object from it. I would think that all I would do is:
AppDelegate *delegate;
When I do this it get an error saying AppDelegate is not defined. The AppDelegate .h and .m files are next to the main file.
Also, when I try to write to a file I don't get an error but it does not write.
The boiler plate code created by XCode (I'm assuming you are using XCode) will create an NSManagedObjectContext for you called *managedObjectContext. If you need to create other objects that are going to interact with your core data model (such as a view controller), you simply pass in that managedObjectContext object as an argument (or link it to a property in your custom class) and interact with it in your custom class. It's worth noting that it's not good practice to be passing around an AppDelegate object in your app. Your app delegate should be at the foundation of your code base and not treated as a typical class. There are definitely times when you will want (or need) to pass the app delegate as an object or reference it in IB, but typically your app will launch in your
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
method and you will launch your primary view controller from there.
Some things in core data also require the persistent store coordinator (such as retrieving managed object ID's), so you may need to pass that in as well. If you need some help working with Core Data, there are a bunch of great articles and books on the subject. I recommend reading as many as you can, since Core Data can be difficult to comprehend at first. It helped me to read a bunch of tutorials at first since everyone explains it a little differently.
Here's a great recent tutorial written on Bindings, Core Data, and working with the app delegate to get you started: http://www.raywenderlich.com/21752/how-to-use-cocoa-bindings-and-core-data-in-a-mac-app
In Cocos2d 2.0, AppDelegate is renamed to AppController
AppController *app = (AppController*)[UIApplication sharedApplication].delegate;
For a Mac graphics application (not iPhone), I need something like a main method in Java, the first method that gets a program going. I've been looking at things like NSViewController and NSWindow object. I've looked around but can't find an answer to this seemingly easy question anywhere. (I am very new at this by the way)
Thanks
If you create a Cocoa project from one of the Xcode "Cocoa Application" templates, you'll get a main.m file that includes the usual startup code.
Try working through one of the tutorial projects that you'll find in the documentation.
If you are using the project templates, the startup code is in the ApplicationDelegate file. The main.m, for a Cocoa application, sets up the run loop, runs NSApplication (as you can see in the Info.plist file under the 'Principle class' key.
This then loads the nib file that is specified in the Info.plist file (under the 'Main nib file base name' key). The default is MainMenu.xib. Now have a look at this nib file.
This is already set up by the template to have a 'Files's Owner' of NSApplication (the class that loaded the nib) But There is also a blue block which represents the application delegate. This is already filled out with one delegate method one outlet.
The delegate method is applicationDidFinishLaunching: This method is called by the application. This is only one of the possible delegate methods that it can handle, but it is sent after the run loop is started but before the application receives any events. It is the common place to put your initialisation code. It is in here that you should start to set up your window, which you can get to using the pre-supplied window outlet.
This is just a quick summary. A handy referenece is on Cocoa With Love and Apple's Introduction to Application Architecture document.
I want to incorporate an applicationDidFinishLaunching: into my cocoa delegate. How would I do this?? On the iphone SDK the applicationDidFinishLaunching is already in the application delegate, but when making my mac application I noticed that there were none.
Best Regards,
Kevin
As of Xcode 3.2, the Mac application template also comes with an application delegate, already connected, that has such a method.
To set this up in a project created before Xcode 3.2, create a new class for your delegate to be an instance of. I usually name mine “AppDelegate”. You'll do this by right-clicking on the Classes group and choosing “Add File”, then picking the Cocoa NSObject Subclass file template.
Open the header you just created (AppDelegate.h). Give it any instance variables you want. Then hit Go to Counterpart. That takes you to the implementation file (AppDelegate.m). Add your applicationDidFinishLaunching: instance method here. Unlike on the iPhone, this is a notification-handler method, so it takes an NSNotification instance and not an NSApplication instance.
Now to hook it up. In the Resources group, open MainMenu.nib. Drag an Object from the Library window into the top-level nib window (the one with icons in it, such as File's Owner and First Responder). Select the object you just created and open the Identity inspector. Set the object's class to AppDelegate, matching the name you used in Xcode. Right-click on the File's Owner, and drag from its delegate outlet to your new object.
In Xcode, add an NSLog statement to your applicationDidFinishLaunching: method. Hit Save All, then Build and Go. Switch back to Xcode and open the Debugger Console. If you did everything right and I didn't forget anything, you should see the log message there.
- (id)init
{
if (self = super init]) {
[NSApp setDelegate:self];
}
return self;
}
You can also do this in Interface Builder; from "File's Owner" in MainMenu.xib, just drag the "delegate" outlet to your object. You may want to consider using -awakeFromNib instead though.
Were you missing the application delegate files altogether? It seems as though there's a bug in the Xcode installation scripts (at least for 3.2.1 on Snow Leopard) that installs the latest project templates in the wrong folder. The older template for a "Cocoa Application" project doesn't contain the delegate files.
I've explained what I've discovered (and how I "fixed" it) in a blog post called Fixing the Xcode Project Templates.
Cheers,
Graham