How to call UIApplicationMain in main.swift in Swift 3

I don't understand how to write a main.swift file in Swift 3 (current toolchain). We used to write it like this:


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


But now that won't compile, because there is a type mismatch between

Process.argv
, which is typed like this:


UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>


and the second parameter to UIApplicationMain, which is typed like this:


UnsafeMutablePointer<UnsafeMutablePointer<Int8>>!


As you can see, they are subtly different. I am able to work around the problem by writing this:


withUnsafeMutablePointer(&Process.unsafeArgv.pointee!) {
    UIApplicationMain(
        Process.argc, $0, nil, NSStringFromClass(AppDelegate)
    )
}


But whether that is safe or correct, I have no idea.

Replies

This seems like fallout from the recent change in how unsafe pointers interact with optional. I think

Process.argv
is correct, in that
Process.argv
itself can’t be nil, but any of the elements it points to can be nil. I recommend that you file a bug against
UIApplicationMain
. Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, radar 26062787 submitted. I'm also going to post this on bugs.swift, as it affects them. They had `@UIApplicationMain` wrong on the last toolchain release, and if the signature of UIApplicationMain changes again, `@UIApplicationMain` will be wrong again.

Jordan Rose has suggested working around it like this:


UIApplicationMain(
    Process.argc, UnsafeMutablePointer<UnsafeMutablePointer<CChar>>(Process.unsafeArgv), nil, NSStringFromClass(AppDelegate)
)

This broke for me in Xcode 8 beta 6. What is the new suggestion?

Like this:


UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory(
            to: UnsafeMutablePointer<Int8>.self,
            capacity: Int(CommandLine.argc)),
    nil,
    NSStringFromClass(AppDelegate.self)
)