We have a custom UIApplication object, so our main.swift was
import Foundation
import UIKit
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(MobileUIApplication), NSStringFromClass(AppDelegate))
and that didn't work in Xcode 8 beta 5 so we used this
//TODO Swift 3 workaround? https://forums.developer.apple.com/thread/46405
UIApplicationMain( Process.argc, UnsafeMutablePointer<UnsafeMutablePointer<CChar>>(Process.unsafeArgv), nil, NSStringFromClass(AppDelegate.self))
On Xcode 8 beta 6 we get Use of unresolved identifier 'Process'
What do we need to do in Xcode 8 beta 6/Swift 3 to define the UIApplicationMain?
I write it this way:
UIApplicationMain(
CommandLine.argc,
UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,
capacity: Int(CommandLine.argc)),
nil,
NSStringFromClass(AppDelegate.self)
)
To change the UIApplication class, substitute NSStringFromClass(MobileUIApplication.self)
for nil
in that formulation.
However, if your only purpose here is to substitute a UIApplication subclass as the shared application instance, there's an easier way: in the Info.plist, add the "Principal class" key and set its value to the string name of your UIApplication subclass, and mark your declaration of that subclass with an @objc(...)
attribute giving it the same Objective-C name.
EDIT This problem is now solved in iOS 12 / Xcode 10. CommandLine.unsafeArgv
now has the correct signature, and one can call UIApplicationMain
easily:
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv,
nil, NSStringFromClass(AppDelegate.self)
)
It seems Process
has been renamed to CommandLine
in beta 6.
CommandLine
But the type of CommandLine.unsafeArgv
is mismatching the second argument of UIApplication
, so you may need to write something like this:
CommandLine.unsafeArgv.withMemoryRebound(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc)) {argv in
_ = UIApplicationMain(CommandLine.argc, argv, NSStringFromClass(MobileUIApplication.self), NSStringFromClass(AppDelegate.self))
}
(UPDATE)This mismatching should be considered as a bug. Generally, you'd better send a bug report when you find "this-should-not-be" things, like the third parameter in beta 5. I hope this "bug" will be fixed soon.
If you just want to designate your custom UIApplication class, why don't you use Info.plist?
NSPrincipalClass | String | $(PRODUCT_MODULE_NAME).MobileUIApplication
(Shown as "Principal class" in non-Raw Keys/Values view.)
With this in your Info.plist, you can use your MobileUIApplication
with normal way using @UIApplicationMain
.
(ADDITION) Header doc of UIApplicationMain
:
// If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no
// NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init.