When create a new project in Cocoa's IDE (like Xcode or AppCode), the IDE configure environment for us. That's great because we can jump into the app logic and make interesting things immediately. However, a lot of starters have no idea about the beginning flow of an app. How the app gets launched? What is AppDelegate indeed? How do xib files and storyboards are loaded and displayed on the screen? We hardly need to config these things ourselves, with the great effort of the IDE developers. But it is always worth to find out what happened under the hood.

In this section, let's focus on the main function. All C and C family programs begin with main function. For an iOS app in Objective-C, when you create a project with Xcode app template, a prepared main.m file will be already in your project. In there is the main function:

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil,
                   NSStringFromClass([AppDelegate class]));
    }
}

In this function, UIApplicationMain from UIKit is invoked. It will initiate an object of UIApplication or its subclass with the third argument (it is nil in this example, which means the default UIApplication will be used). The last argument specifies which class to be used as the app delegate. An instance of it will be created in UIApplicationMain and set as the delegate property of UIApplication object. This object is used to receive some life cycle methods like didFinishLaunching and didEnterBackground. Although UIApplicationMain returns an int, it will never return and be left in the memory, until the system or user kills it.

Things changed a little in Swift. When you create an iOS project in Swift, there is no main file in the project anymore, neither the main function. The only thing seems to be related to main would be the attribute of @UIApplicationMain, which is above the default AppDelegate class declaration.

This attribute holds the key here. By marking a class as @UIApplicationMain, the compiler will know which type should perform as the app delegate. Other things are more likely boilerplate code, so they are inserted in compiling time automatically. To verify it, we can try to remove the @UIApplicationMain attribute, which will cause an error when compiling:

Undefined symbols _main

It cannot find the main function.

Generally speaking, there is no need to change it, except one situation. If we want to use a subclass of UIApplication as our application class, we need to rewrite this part and add main function manually.

As you see above, Swift app also needs a main function to compile. Similar as main.c in C or main.m in Objective-C, there could be a special file named as main.swift in Swift. In this file, we can write statement code without defining any type or scope. These statements will be executed as traditional main function. Take an example, after removing @UIApplicationMain attribute, we create a main.swift file in the project and fill it with:

UIApplicationMain(Process.argc, Process.unsafeArgv, nil,
    NSStringFromClass(AppDelegate))

The error will disappear and everything goes well. Now we can use our UIApplication subclass instead of the default one to do some useful things we want. Just like this:

import UIKit

class MyApplication: UIApplication {
    override func sendEvent(event: UIEvent!) {
        super.sendEvent(event)
        print("Event sent: \(event)");
    }
}

UIApplicationMain(Process.argc, Process.unsafeArgv,
    NSStringFromClass(MyApplication), NSStringFromClass(AppDelegate))

It will log out every sending event in the entire app (button clicking event, for example).