Apple Reference, Articles, and Opinions

C to Swift - Article 1

From main() to @main

In C programs, the main function is The entry point of the program. You would get a pretty nasty compilation error if you add another function anywhere in your source code files with the same name.

Most of my exposure early on in C/C++ was through the use of command line tools. As such, that is what I will use to expose the difference between main function and its role in either language.

Let’s start by creating a simple command line macOS project in Xcode and in the drop down menu

We can see that the file created is one file called main.c and the program has one function called main with two arguments. Of course this template program just prints the classic programming phrase.

#include <stdio.h>

int main(int argc, const char * argv[]) {

	printf("Hello, World!\n”); // C++ you could also use something like std::cout here
	return 0;
}

You might be familiar with the arguments argc and argv if you have a C background, but you could remove them if you aren’t providing any command line arguments to the main function.

Contrast the above program with the what you get when you select Swift as the programming language when creating the project. You get one file called main.swift that contains this code

import Foundation

print("Hello, World!")

This program is just one line of code and although the syntax is nice because it’s on one line, it’s not very clear how this works. Let’s try and figure out what’s going on…

Firstly, I should mention that the main.c file can be named anything and it will still compile just fine. The fact that the file name is main has no impact when compiling. This is because C compilers look for the main method without much care to what the file names are called.

As it turns out, in the official Swift documentation here it states the following with regard to the entry point

"The Swift code you compile to make an executable can contain at most one of the following approaches to mark the top-level entry point, regardless of how the code is organized into files and modules: the main attribute, the NSApplicationMain attribute, the UIApplicationMain attribute, a main.swift file, or a file that contains top-level executable code."

So, that solves the why of how the Xcode template program works - Because the swift file is named main.swift it is the entry point for this command line program. Chances are if you are coming from C, you are probably trying to learn how to write applications for one of Apple’s platforms such as iOS or macOS so it’s worth mentioning that when you create a single view application, you are not given a main.swift file. Instead you are given a bunch of files that in the beginning can seem very overwhelming if you’re used to writing your code from scratch like I was. This is where the Swift attributes @main and @ UIApplicationMain come in.

Since Xcode 12 - Swift 5.3, the @UIApplicationMain attribute seems to have been replaced in favor of @main when creating a new GUI App in Xcode. The documentation in Swift is a bit difficult to understand since you can still use either one. In short, the @main attribute is looking for a main method somewhere in the proceeding class or struct definition. In a GUI app, this works because your app delegate UIApplicationDelegate has a main method pre defined and satisfies this requirement and your AppDelegate class conforms to that protocol by default.

The code produced in a basic Xcode app project is like so

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
	// Beast code…
}

Prior to Xcode 12 it looked like this..

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate {
	// Beast code…
}

The only difference is in the attribute before the AppDelegate class definition. The UIApplicationDelegate protocol was extended in Swift 5.3 to include a main function. This extension allows us to use the @main attribute instead of @UIApplicationDelegate attribute. By using the latter to define the entry point of your application, you are calling the deprecated function UIApplicationMain which uses the class name you are defining as the delegate class for the app. This is important for when the application goes into the background as in when the user presses the home button.

If you were not conforming to the UIApplicationDelegate protocol, you could still use either attribute however if you were to use @main you would have to have a static method named main that returns void like so

@main
struct MyTopLevel {
	static func main() {
		print("Hello, World!")
	}
}

To use the @UIApplicationMain attribute alone you would have to call the deprecated function UIApplicationMain(:, :, :, :) which is why using @main is preferred. Calling UIApplicationMain is similar to calling the C main function.

import UIKit //Necessary to use UIApplicationMain 

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, nil)

The last option we have not yet discussed is the …or a file that contains top-level executable code option. This, I believe is to facilitate Swift scripting and not particular useful for application development. You can write a small program with executable code as below and then run it in the Terminal by typing $ swift example.swift and the program will execute the code top-down.

let strings = ["apples", "oranges", "bananas"]
for string in strings {
	print(string)
}

In summary, use the @main attribute to define an entry point into the program. You would then create a custom class that either conforms to the UIApplicationDelegate protocol or define the static main method in your custom class.

That is it for my second article about programming in Swift for C developers. I hope you enjoyed it! If you have any comments or questions, or would like to inquire about freelance development help, please reach out via email or via Twitter

Thanks for reading!

With gratitude,
Jav Solo