NSApplication
An object that manages an app’s main event loop and resources used by all of that app’s objects.
Declaration
class NSApplicationMentioned in
Overview
Every app uses a single instance of NSApplication to control the main event loop, keep track of the app’s windows and menus, distribute events to the appropriate objects (that’s, itself or one of its windows), set up autorelease pools, and receive notification of app-level events. An NSApplication object has a delegate (an object that you assign) that’s notified when the app starts or terminates, is hidden or activated, should open a file selected by the user, and so forth. By setting the delegate and implementing the delegate methods, you customize the behavior of your app without having to subclass NSApplication. In your app’s main() function, create the NSApplication instance by calling the shared class method. After creating the application object, the main() function should load your app’s main nib file and then start the event loop by sending the application object a run() message. If you create an Application project in Xcode, this main() function is created for you. The main() function Xcode creates begins by calling a function named NSApplicationMain(), which is functionally similar to the following:
void NSApplicationMain(int argc, char *argv[]) {
[NSApplication sharedApplication];
[NSBundle loadNibNamed:@"myMain" owner:NSApp];
[NSApp run];
}The shared class method initializes the display environment and connects your program to the window server and the display server. The NSApplication object maintains a list of all the NSWindow objects the app uses, so it can retrieve any of the app’s NSView objects. The shared method also initializes the global variable NSApp, which you use to retrieve the NSApplication instance. shared only performs the initialization once. If you invoke it more than once, it returns the application object it created previously.
The shared NSApplication object performs the important task of receiving events from the window server and distributing them to the proper NSResponder objects. NSApp translates an event into an NSEvent object, then forwards the event object to the affected NSWindow object. All keyboard and mouse events go directly to the NSWindow object associated with the event. The only exception to this rule is if the Command key is pressed when a key-down event occurs; in this case, every NSWindow object has an opportunity to respond to the event. When a window object receives an NSEvent object from NSApp, it distributes it to the objects in its view hierarchy.
NSApplication is also responsible for dispatching certain Apple events received by the app. For example, macOS sends Apple events to your app at various times, such as when the app is launched or reopened. NSApplication installs Apple event handlers to handle these events by sending a message to the appropriate object. You can also use the NSAppleEventManager class to register your own Apple event handlers. The applicationWillFinishLaunching(_:) method is generally the best place to do so. For more information on how events are handled and how you can modify the default behavior, including information on working with Apple events in scriptable apps, see How Cocoa Applications Handle Apple Events in Cocoa Scripting Guide.
The NSApplication class sets up @autorelease block during initialization and inside the event loop—specifically, within its initialization (or shared) and run() methods. Similarly, the methods AppKit adds to Bundle employ @autorelease blocks during the loading of nib files. These @autorelease blocks aren’t accessible outside the scope of the respective NSApplication and Bundle methods. Typically, an app creates objects either while the event loop is running or by loading objects from nib files, so this lack of access usually isn’t a problem. However, if you do need to use Cocoa classes within the main() function itself (other than to load nib files or to instantiate NSApplication), you should create an @autorelease block to contain the code using the classes.
The delegate and notifications
You can assign a delegate to your NSApplication object. The delegate responds to certain messages on behalf of the object. Some of these messages, such as application(_:openFile:), ask the delegate to perform an action. Another message, applicationShouldTerminate(_:), lets the delegate determine whether the app should be allowed to quit. The NSApplication class sends these messages directly to its delegate.
NSApplication also posts notifications to the app’s default notification center. Any object may register to receive one or more of the notifications posted by NSApplication by sending the message addObserver(_:selector:name:object:) to the default notification center (an instance of the NSNotificationCenter class). The delegate of NSApplication is automatically registered to receive these notifications if it implements certain delegate methods. For example, NSApplication posts notifications when it’s about to be done launching the app and when it’s done launching the app (willFinishLaunchingNotification and didFinishLaunchingNotification). The delegate has an opportunity to respond to these notifications by implementing the methods applicationWillFinishLaunching(_:) and applicationDidFinishLaunching(_:). If the delegate wants to be informed of both events, it implements both methods. If it needs to know only when the app is finished launching, it implements only applicationDidFinishLaunching(_:).
System services
NSApplication interacts with the system services architecture to provide services to your app through the Services menu.
Subclassing notes
You rarely should find a real need to create a custom NSApplication subclass. Unlike some object-oriented libraries, Cocoa doesn’t require you to subclass NSApplication to customize app behavior. Instead it gives you many other ways to customize an app. This section discusses both some of the possible reasons to subclass NSApplication and some of the reasons not to subclass NSApplication.
To use a custom subclass of NSApplication, send shared to your subclass rather than directly to NSApplication. If you create your app in Xcode, you can accomplish this by setting your custom app class to be the principal class. In Xcode, double-click the app target in the Groups and Files list to open the Info window for the target. Then display the Properties pane of the window and replace “NSApplication” in the Principal Class field with the name of your custom class. The NSApplicationMain function sends shared to the principal class to obtain the global app instance (NSApp)—which in this case will be an instance of your custom subclass of NSApplication.
Methods to override
Generally, you subclass NSApplication to provide your own special responses to messages that are routinely sent to the global app object (NSApp). NSApplication doesn’t have primitive methods in the sense of methods that you must override in your subclass. Here are four methods that are possible candidates for overriding:
Override run() if you want the app to manage the main event loop differently than it does by default. (This a critical and complex task, however, that you should only attempt with good reason).
Override sendEvent(_:) if you want to change how events are dispatched or perform some special event processing.
Override requestUserAttention(_:) if you want to modify how your app attracts the attention of the user (for example, offering an alternative to the bouncing app icon in the Dock).
Override target(forAction:) to substitute another object for the target of an action message.
Special considerations
The global app object uses @autorelease blocks in its run() method; if you override this method, you’ll need to create your own @autorelease blocks.
Do not override shared. The default implementation, which is essential to app behavior, is too complex to duplicate on your own.
Alternatives to subclassing
NSApplication defines numerous Delegation methods that offer opportunities for modifying specific aspects of app behavior. Instead of making a custom subclass of NSApplication, your app delegate may be able to implement one or more of these methods to accomplish your design goals. In general, a better design than subclassing NSApplication is to put the code that expresses your app’s special behavior into one or more custom objects called controllers. Methods defined in your controllers can be invoked from a small dispatcher object without being closely tied to the global app object.
Topics
Getting the shared app object
Managing the app’s behavior
Managing the event loop
nextEvent(matching:until:inMode:dequeue:)discardEvents(matching:before:)currentEventisRunningrun()finishLaunching()stop(_:)sendEvent(_:)postEvent(_:atStart:)
Posting actions
Terminating the app
Activating and deactivating the app
Passing control from one app to another with cooperative activationactivate()deactivate()isActiveyieldActivation(to:)yieldActivation(toApplicationWithBundleIdentifier:)NSApplication.ActivationOptions
Managing relaunch on login
Managing remote notifications
registerForRemoteNotifications()unregisterForRemoteNotifications()enabledRemoteNotificationTypesregisterForRemoteNotifications(matching:)isRegisteredForRemoteNotificationsNSApplication.RemoteNotificationType
Managing the app’s appearance
appearanceeffectiveAppearancecurrentSystemPresentationOptionspresentationOptionsNSApplication.PresentationOptionsapplicationShouldSuppressHighDynamicRangeContent
Managing windows, panels, and menus
User interface layout direction
Accessing the dock tile
Customizing the Touch Bar
Managing user attention requests
requestUserAttention(_:)NSApplication.RequestUserAttentionTypecancelUserAttentionRequest(_:)reply(toOpenOrPrint:)NSApplication.DelegateReply
Providing help information
registerUserInterfaceItemSearchHandler(_:)searchString(_:inUserInterfaceItemString:range:found:)unregisterUserInterfaceItemSearchHandler(_:)showHelp(_:)activateContextHelpMode(_:)helpMenu
Providing services
Determining access to the keyboard
Hiding apps
Managing threads
Logging exceptions
Configuring the activation policy
Scripting your app
Notifications
didBecomeActiveNotificationdidChangeScreenParametersNotificationdidFinishLaunchingNotificationdidHideNotificationdidResignActiveNotificationdidUnhideNotificationdidUpdateNotificationwillBecomeActiveNotificationwillFinishLaunchingNotificationwillHideNotificationwillResignActiveNotificationwillTerminateNotificationwillUnhideNotificationwillUpdateNotificationdidFinishRestoringWindowsNotificationdidChangeOcclusionStateNotification
Loading Cocoa bundles
Displaying high dynamic resolution (HDR) content
applicationShouldSuppressHighDynamicRangeContentNSApplication.ShouldBeginSuppressingHighDynamicRangeContentNSApplication.ShouldEndSuppressingHighDynamicRangeContent