Xcode Cocos2d Can't Create AppDelegate Object - objective-c

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;

Related

AppDelegate instantiated last on launch

I'm very comfortable with writing iOS apps, but OS X unexpectedly seems somewhat alien.
Here's the question upfront (read on for context):
When my application launches using the .xib set in the Main Interface field under the deployment info of my apps target, why does the AppDelegate get instantiated after the ViewControllers?
Context (no pun intended):
The reason I ask is because I'm using Core Data (spare me any heckling for this decision), and typically you keep a pointer to the MOC (Managed Object Context) in AppDelegate. One of my controllers is trying to get this MOC instance variable but the AppDelegate instance isn't around yet and therefore my app doesn't present data just after launch.
The AppDelegate and the two ViewControllers are in the .xib. The VCs are hooked to views inside a split view. They're trying to use the MOC in viewDidLoad to make queries. They are accessing the AppDelegate like this:
let delegate = NSApplication.sharedApplication().delegate as AppDelegate
let moc = delegate.managedObjectContext
This will crash as the .delegate property of the sharedApplication() returns nil.
I tried making an NSWindowController from the .xib in applicationDidFinishLaunching and removing the .xib from the Main Interface field, but then applicationDidFinishLaunching doesn't get called at all.
I've ensured that all the connections in IB for from the Application and the Files Owner (NSApplcation) delegate IBOutlets to the AppDelegate have been made.
UPDATE - 31/03/15
Stephen Darlington's answer below offers a good solution for my/this case. And as I understand it's actually better to setup the MOC in the way he's suggested.
If a correct answer arrives that explains why the AppDelegate is being instantiated at some later time in the launch process, I'll mark it correct instead of Stephen's. Thanks Stephen!
The "easy" solution would be to have managedObjectContext create a MOC if one doesn't exist (i.e., change it from a property to a method). That way which ever code gets there first the stack will be available.
(I'll spare the lectures about both creating the Core Data stack in the app delegate and accessing the app delegate like that!)
Here's another option without having to subclass NSApplication:
Don't put your view controllers in the .xib that you set as the Main Interface, just have the Main Menu (menu bar), AppDelegate and Font Manager in there.
Then make your view controllers in other .xibs.
Then in the applicationDidFinishLaunching method init your view controllers from their .xib files.
I also faced this issue with setting up Parse. To get around it, I simply subclassed NSApplication and set it as the Principle class in the Info.plist. In your NSApplication subclass, override the init methods and initialise Parse or anything else you need to, there.

Why Apple's sample code project IKImageViewDemo does not have an AppDelegate class?

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.

Sharing a Core Data Database between view controllers in a UITabBarController

I am working on an application which uses a UITabBarViewController to hold two UITableViewControllers.
In the Story Board, I pull out the two UITableVIewControllers which are called firstTVC & secondTVC and then embed them in a UITabBarController.
I have a UIDocument #property with a fetchedResultsController in firstTVC that works great, but I haven't figured out how to pass the ManagedObjectContext #property from firstTVC to secondTVC.
I have thought about doing it in the app delegate, but I have read that it is considered taboo (especially in iOS 5).
Thanks for reading!
Caborca,
Apple's standard Core Data template maintains the MOC on the AppDelegate. Why do you have a problem using it? (Yes, some folks believe all singletons are "code smell.") That said, this is hanging off of a singleton defined by the Cocoa Touch framework. It already exists and is available everywhere in your code.
If that doesn't work for you and you are instantiating via nibs, then you are going to need to create a custom delegate or read the singleton and store it locally in your -viewDidLoad method.
Andrew

Execute NSFetchRequest on application startup

In another question ( Accessing an NSApplications delegate in another class? ) I asked about calling the Application's delegate because I needed it's managedObjectContext for a fetch request. However, when I try to let all values be displayed in an NSTableView on application startup, I'm running into problems. DataController, my NSTableViewDataSource, calls it's init-method before my application delegate calls it's applicationWillFinishStartup or any other method to initialize the managedObjectContext. What am I doing wrong? How else can I fill an NSTableView with already existing objects?
You should access managedObjectContext only via its getter, even from DataController, as in [appDelegate managedObjectContext] or appDelegate.managedObjectContext.
Your managedObjectContext method should automatically set up the managed object context; you shouldn't write an explicit moc setup routines in your applicationDidFinishLaunching, etc. And the standard core-data template is written that way.
Now, for this to work, the app delegate needs to be properly set up from the point of view of DataController. However, init is called before all the IBOutlet is set up, so that's the wrong place to perform setup operations of objects inside the nib. Instead, use awakeFromNib to do these things. awakeFromNib is sent to every object after the IBOutlet etc. are all set up.
That said, writing your own DataController is a total waste of time. Just instantiate the standard NSArrayController in the nib file, and use it in the Core Data mode via binding. There's absolutely no need for you to write the fetch request by yourself. Study Apple's own CoreData sample codes and then google "Binding CoreData Tutorial" for many tutorials available on-line.

AppDelegate file missing in Xcode 3.1?

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.