What does @UIApplicationMain mean?
The @UIApplicationMain
attribute in Swift replaces the trivial main.m
file found in Objective-C projects (whose purpose is to implement the main
function that's the entry point for all C programs and call UIApplicationMain
to kick off the Cocoa Touch run loop and app infrastructure).
In Objective-C, the main (heh) bit of per-app configuration that the UIApplicationMain
function provides is designating one of your app's custom classes as the delegate of the shared UIApplication
object. In Swift, you can easily designate this class by adding the @UIApplicationMain
attribute to that class' declaration. (You can also still invoke the UIApplicationMain
function directly if you have reason to. In Swift you put that call in top-level code in a main.swift
file.)
@UIApplicationMain
is for iOS only. In OS X, the app delegate is traditionally set in the main nib file designated by the Info.plist (the same for Swift as for ObjC) — but with OS X storyboards there's no main nib file, so @NSApplicationMain
does the same thing there.
What does @main mean in Xcode 12?
UIApplicationMain first instantiates UIApplication
and retains its instance to serve as the shared application instance (UIApplication.shared
) and then instantiates the app delegate marked @Main
as the application instance's delegate. The main
method exists as a type method.
What is the differnce between @main and @uiapplicationmain
All code has an entry point: the place where whoever calls that code actually calls. How does the whole program, comprising many Swift files, actually get started? We need an entry point for the whole program, which the runtime will call to launch us.
In Swift, this is the main.swift file. Its job is to call UIApplicationMain, which creates some instances including the app and the app delegate and gets the event loop running (and stays running for the rest of the time the app runs). A minimal main.swift file would have to look like this:
import UIKit
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv, nil,
NSStringFromClass(AppDelegate.self)
)
However, no one ever uses a main.swift file! It's boilerplate, so why bother? Instead, you say @main
, and a main.swift file is generated for you behind the scenes. In particular, you put the attribute @main
on your AppDelegate class, so the main.swift generator knows which class to instantiate as your application delegate.
Two more things to know:
Before Swift 5.3,
@main
was called@UIApplicationMain
instead. From that point of view, they are identical, two names for the same thing.New in Swift 5.3 and Xcode 12, you can designate one of your own types as
@main
and give it a staticmain
function, where you do whatever you would have done in the main.swift file. That is something@UIApplicationMain
cannot do:
@main
struct MyMain {
static func main() -> Void {
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self)
)
}
}
(Swift) Error: UIApplicationMain attribute cannot be used in a module
Apparently the Adventure project doesn't compile correctly in Xcode6-Beta5. However, Xcode6-Beta6 compiles and runs it just fine.
As for the error encountered after upgrading to Beta6, the way to fix that is to delete the derived data for the project. To do that, open the Organizer ("Window" menu -> "Organizer"), select the "Adventure" project on the left side of the window, then click the "Delete" button associated with the project's derived data (should be the top one on the far right).
'UIApplicationMain' attribute cannot be used in a module that contains top-level code
Ok, I finally solved it myself. It seems there was another file buried within a library I added called main.swift which was conflicting with my AppDelegate. I deleted it and the issue went away.
Proper use of UIApplicationMain
This function is declared as
int UIApplicationMain (
int argc,
char *argv[],
NSString *principalClassName,
NSString *delegateClassName
);
Since you did not subclass UIApplication, pass nil
to the 3rd argument. But you have a custom UIApplicationDelegate. So pass its class name to the 4th argument.
int retval = UIApplicationMain(argc, argv, nil, @"AppDelegate");
React Native app purely in Swift
This excellent post helped me solving the problem.
Solution
- Add Bridging Header
#import "RCTBridgeModule.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTRootView.h"
#import "RCTUtils.h"
#import "RCTConvert.h"
- Add AppDelegate.Swift
var bridge: RCTBridge!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
/**
* Loading JavaScript code - uncomment the one you want.
*
* OPTION 1
* Load from development server. Start the server from the repository root:
*
* $ npm start
*
* To run on device, change `localhost` to the IP address of your computer
* (you can get this by typing `ifconfig` into the terminal and selecting the
* `inet` value under `en0:`) and make sure your computer and iOS device are
* on the same Wi-Fi network.
*/
let jsCodeLocation = NSURL(string: "http://localhost:8081/index.ios.bundle?platform=ios&dev=true")
/**
* OPTION 2
* Load from pre-bundled file on disk. The static bundle is automatically
* generated by "Bundle React Native code and images" build step.
*/
// jsCodeLocation = NSBundle.mainBundle().URLForResource("main", withExtension: "jsbundle")
let rootView = RCTRootView(bundleURL:jsCodeLocation as URL!, moduleName: "PropertyFinder", initialProperties: nil, launchOptions:launchOptions)
self.bridge = rootView?.bridge
self.window = UIWindow(frame: UIScreen.main.bounds)
let rootViewController = UIViewController()
rootViewController.view = rootView
self.window!.rootViewController = rootViewController;
self.window!.makeKeyAndVisible()
return true
}
Remove the
AppDelegate.h
,AppDelegate.m
and the main file.Clean and build your project.
Related Topics
What Is an Optional Value in Swift
How to Enumerate an Enum With String Type
Append Text or Data to Text File in Swift
Biginteger Equivalent in Swift
Multiple Sheet(Ispresented:) Doesn't Work in Swiftui
Getting the Decimal Part of a Double in Swift
Why My Return Is Nil But If I Press the Url in Chrome/Safari, I Can Get Data
How to Check If a Firebase Database Value Exists
What Happened to the Uiview() Constructor in Swift 3.0
Sharing Userdefaults Between Extensions
In Swiftui, How to Increase the Height of a Button
JavaScript Synchronous Native Communication to Wkwebview
Get Nth Character of a String in Swift Programming Language
Structure VS Class in Swift Language
Do Swift-Based Applications Work on Os X 10.9/Ios 7 and Lower