What do @main, @UIApplicationMain, and @NSApplicationMain mean

⋅ 4 min read ⋅ Swift Development

Table of Contents

When you open an AppDelegate file, you usually see either of these attributes (@main, @UIApplicationMain, and @NSApplicationMain) over your class declaration.

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
....
}

These attributes help define an entry point for your application. To appreciate their work, we need to know a little bit about how a Swift application works, which we will find out in this article.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Order-independent

A Swift application is composed of any number of files working together. Most Swift files are order-independent, meaning you can use a type before it is defined. You can even import modules at the bottom of the file if you want to.

Here is a valid Swift file.

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 1
let foo = Foo()
}
}

// 2
struct Foo {

}

// 3
import UIKit

1 We declare an instance of Foo, which define later down in the file 2.
3 We declare a subclass of UIViewController at the beginning of the file but import its framework at the bottom.

In this order-independent world, there is one rule to keep all files living in peace and harmony. Top-level code is not allowed in most of your Swift files. Top-level code means any executable statement not written within a function body, within a class, or otherwise encapsulated. If we think about it, it makes perfect sense. How would we determine how top-level code runs in this order-independent world. If this is allowed, your app could perform differently for each execution.

Adding top-level code in most of your Swift files will result in a compile error.

Expressions are not allowed at the top level.
Expressions are not allowed at the top level.

Application entry points

You might notice that we use the word Most not All when mentioning that Swift files are order-independent and top-level code is not allowed.

Most Swift files are order-independent...

Top-level code is not allowed in most of your Swift files.

Due to an order-independent nature, top-level code is not allowed. But the runtime needs to know where to start our app. It needs an entry point where it can execute our app.

The entry point in Swift is a special file named "main.swift". The main.swift file can contain top-level code, and it run in order-dependent manner. And this is the only file that gets the exception.

Here is how a main.swift file looks like, it creates an application object and application delegate for our app. This acts as an entry point for your application.

import UIKit

UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
nil,
NSStringFromClass(AppDelegate.self)
)

You can use this to launch a custom subclass of UIApplication. You can do that by specifying it in a third argument.

This is an example where we try to launch a custom subclass of UIApplication.

class MyApplication: UIApplication {}

UIApplicationMain(
CommandLine.argc,
CommandLine.unsafeArgv,
NSStringFromClass(MyApplication.self),
NSStringFromClass(AppDelegate.self)
)

But you rarely need to do that. So, most of the time, the main.swift is just a boilerplate code. This is where @main, @UIApplicationMain, and @NSApplicationMain are trying to help. They generate this boilerplate code behind the scene.

In the past, macOS templates will include a "main.swift" file for you, but you won't see this anymore in the new version of Xcode. Depending on your Xcode version, you will only see either the @main, @UIApplicationMain, @NSApplicationMain attributes.

Create your own entry point

If you try creating main.swift and run the app, you will get the following compile error.

'main' attribute cannot be used in a module that contains top-level code.
'main' attribute cannot be used in a module that contains top-level code.

That's because we just replicate the @main attribute work by creating an entry point. To make our app run again, simply remove the @main attribute from the AppDelegate.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

What do @main, @uiapplicationmain, and @nsapplicationmain mean?

@main, @UIApplicationMain, and @NSApplicationMain are attributes that cause the compiler to synthesize an entry point for our application and eliminate the need for a "main.swift" file.


Read more article about Swift, Development, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
How to position an UIButton image to the right side of the text

By default, when you set an image to an UIButton, it will position on the leading edge of the text. Let's learn how to put it on the trailing edge instead.

Next
How to disable dark mode in iOS

If you are not ready to make your app support dark mode, you can opt-out of that. You can do disable it for an entire app or partially. Learn different ways to disable dark mode in iOS.

← Home