Skip to content

Latest commit

 

History

History
117 lines (92 loc) · 5.54 KB

0383-deprecate-uiapplicationmain-and-nsapplicationmain.md

File metadata and controls

117 lines (92 loc) · 5.54 KB

Deprecate @UIApplicationMain and @NSApplicationMain

Introduction

@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.

Motivation

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.

Proposed 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.

Detailed design

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.

Source compatibility

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.

Effect on ABI stability

This proposal has no impact on ABI.

Effect on API resilience

None.