I read a post to use macro to reference AppDelegate. I wonder what I should use to replace (MyOwnAppDelegate*)
#define AppDelegate ((MyOwnAppDelegate*)[[UIApplication sharedApplication] delegate])
If you're referencing the UIApplicationDelegate so often that you need a special macro for it, then you're referencing it too often. The application delegate is the delegate of the main UIApplication object. It is not a general place to store "stuff." See the following discussions:
What describes the Application Delegate best? How does it fit into the whole concept?
Is it ok to place most logic and models in the appDelegate?
If it's a more recently started project, your delegate is probably called AppDelegate. To find out, you have to find the class in your project that implements NSApplicationDelegate or UIApplicationDelegate (depending on your target platform).
Related
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.
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.
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;
I'm quite new to OOP and design patterns, but I've implemented the Singleton pattern once before to pass static arrays and string objects between different ViewControllers.
I was wondering if there was an easy way to have all my ViewControllers listen for a gesture or event, and then execute some code once said gesture/event occurs. I was thinking of either using the UIGestureRecognizer object or motionBegan method of the UIResponder class.
I've already gotten this working by making a new UIWindow class, lodging the code in there, and changing the class of MainWindow.xib to my custom class. This works, and is a nice solution, but I'm still wondering if there's a non-IB way of implementing this solution (e.g., singletons)
Thanks ahead of time for your guidance.
Sample code is greatly appreciated!
You subclassed UIWindow? That's very uncommon. Read about the UIApplication delegate object, and the delegate pattern in general. It's basically your app's main singleton in Cocoa.
If you don't want to pass it around, you can always retrieve the app's delegate by calling
[[UIApplication sharedApplication] delegate]
If you want lots of unconnected objects/controllers to be notified of a single event, you can trigger it however you like (target/action from a control(s) or gesture recognizer(s)).
You might want to look into NSNotificationCenter and NSNotification, you could have multiple objects listing for the notification of the event/change.
I asked a question about quitting an App when windows close, and the answer was to use delegates :
There is a optional method for the application's delegate which will do this
automatically. All you have to due is add this to the implementation. You don't need to create an outlet or anything.
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
return YES;
}
It definitely works, but you may have put the code in the wrong place. Make sure it's in your application's delegate.
I'm not sure how can I put the applicationShouldTerminateAfterLastWindowClosed in the application's delegate?
Your xcode project should have created an application delegate class when the project was created. The only thing you need to do to implement this in your delegate is to add the method into the delegate .m file (you don't need to worry about the .h file since the method is already declared as part of the application delegate protocol).
So you have the class called RubichevAppDelegate. Put the method into the .m file.
PS. You forgot the opening brace in your code.