- Proposal: SE-0383
- Authors: Robert Widmann
- Review Manager: John McCall
- Status: Implemented (Swift 5.10)
- Upcoming Feature Flag:
DeprecateApplicationMain
- Implementation: PR 62151
- Review: (pitch) (review) (acceptance)
@UIApplicationMain
and @NSApplicationMain
used to be the standard way for
iOS and macOS apps respectively to declare a synthesized platform-specific
entrypoint for an app. These functions have since been obsoleted by
SE-0281's
introduction of the @main
attribute, and they now represent a confusing bit of
duplication in the language. This proposal seeks to deprecate these alternative
entrypoint attributes in favor of @main
in pre-Swift 6, and it makes their use
in Swift 6 a hard error.
UIKit and AppKit have fully embraced the @main
attribute and have made
adoption by applications as simple as conforming to the UIApplicationDelegate
and NSApplicationDelegate
protocols. This now means that an author of an
application is presented with two different, but ultimately needless, choices
for an entrypoint:
- use one of the hard coded framework-specific attributes
@UIApplicationMain
or@NSApplicationMain
, or - use the more general
@main
attribute.
At runtime, the behavior of the @main
attribute on classes that conform to
one of the application delegate protocols above is identical to the corresponding
framework-specific attribute. Having two functionally identical ways to express the
concept of an app-specific entrypoint is clutter at best and confusing at worst.
This proposal seeks to complete the migration work implied by
SE-0281
by having the compiler push Swift authors towards the more general, unified
solution.
Using either @UIApplicationMain
and @NSApplicationMain
in a pre-Swift 6
language mode will unconditionally warn and offer to replace these attributes
with the appropriate conformances. In Swift 6 language mode (and later), using
these attributes will result in a hard error.
Because
@UIApplicationMain
and@NSApplicationMain
are used in identical ways, this portion of the document will only discuss@UIApplicationMain
. The design for@NSApplicationMain
follows the exact same pattern.
Framework-specific attributes were added to the language to automate the
boilerplate involved in declaring a standard application entrypoint. In UIKit
code, the entrypoint always ends with a call to UIApplicationMain
. The last
parameter of this call is the name of a subclass of UIApplicationDelegate
.
UIKit will search for and instantiate this delegate class so it can issue
application lifecycle callbacks. Swift, therefore, requires this attribute to
appear on a class that conforms to the UIApplicationDelegate
protocol so it
can provide the name of that class to UIKit.
But a conformance to UIApplicationDelegate
comes with more than just lifecycle
callbacks. A default implementation of a main
entrypoint is provided for
free
to a conforming type, but the @UIApplicationMain
attribute suppresses it. This
fact is key to the migration path for existing users of the framework-specific
attribute.
Under this proposal, when the compiler sees a use of @UIApplicationMain
, it
will emit a diagnostic including a suggestion to replace the attribute with
@main
. In Swift 6 and later language modes, this diagnostic will be an error;
otherwise it will be a warning.
@UIApplicationMain // warning: '@UIApplicationMain' is deprecated in Swift 5
// fixit: Change `@UIApplicationMain` to `@main`
final class MyApplication: UIResponder, UIApplicationDelegate {
/**/
}
Once the fixit has been applied, the result will be
@main
final class MyApplication: UIResponder, UIApplicationDelegate {
/**/
}
This simple migration causes the compiler to select the main
entrypoint
inherited by the conformance to UIApplicationDelegate
. No further source
changes are required.
Current Swift libraries will continue to build because they compile under pre-Swift 6 language modes. Under such language modes this proposal adds only an unconditional warning when framework-specific entrypoints are used, and provides diagnostics to avoid the warning by automatically migrating user code.
In Swift 6 and later modes, this proposal is intentionally source-breaking as the
compiler will issue an unconditional error upon encountering a framework-specific
attribute. This source break will occur primarily in older application code, as
most libraries and packages do not use framework-specific attributes to define a main
entrypoint. Newer code, including templates for applications provided by Xcode 14
and later, already use the @main
attribute.
This proposal has no impact on ABI.
None.