What Does "@Uiapplicationmain" Mean

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 static main 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

  1. Add Bridging Header
#import "RCTBridgeModule.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTRootView.h"
#import "RCTUtils.h"
#import "RCTConvert.h"

  1. 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
}

  1. Remove the AppDelegate.h, AppDelegate.m and the main file.

  2. Clean and build your project.



Related Topics



Leave a reply



Submit