Xcode 8 beta 6:main.swift 无法编译
Xcode 8 beta 6: main.swift won't compile
我们有一个自定义的 UIApplication 对象,所以我们的 main.swift 是
import Foundation
import UIKit
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(MobileUIApplication), NSStringFromClass(AppDelegate))
这在 Xcode 8 beta 5 中不起作用,所以我们使用了这个
//TODO Swift 3 workaround? https://forums.developer.apple.com/thread/46405
UIApplicationMain( Process.argc, UnsafeMutablePointer<UnsafeMutablePointer<CChar>>(Process.unsafeArgv), nil, NSStringFromClass(AppDelegate.self))
在 Xcode 8 beta 6 上,我们得到 使用未解析的标识符 'Process'
我们需要在 Xcode 8 beta 6/Swift 3 中做什么来定义 UIApplicationMain?
似乎 Process
在 beta 6 中已重命名为 CommandLine
。
但是CommandLine.unsafeArgv
的类型与UIApplication
的第二个参数不匹配,所以你可能需要这样写:
CommandLine.unsafeArgv.withMemoryRebound(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc)) {argv in
_ = UIApplicationMain(CommandLine.argc, argv, NSStringFromClass(MobileUIApplication.self), NSStringFromClass(AppDelegate.self))
}
(更新)这种不匹配应该被视为一个错误。一般情况下,发现"this-should-not-be"的时候最好发一个bug report,比如beta 5的第三个参数,希望这个"bug"能尽快修复
如果您只想指定自定义 UIApplication class,为什么不使用 Info.plist?
NSPrincipalClass | String | $(PRODUCT_MODULE_NAME).MobileUIApplication
(在 non-Raw Keys/Values 视图中显示为 "Principal class"。)
在您的 Info.plist 中有了这个,您就可以使用 @UIApplicationMain
的正常方式使用您的 MobileUIApplication
。
(添加)Header 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.
我是这样写的:
UIApplicationMain(
CommandLine.argc,
UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,
capacity: Int(CommandLine.argc)),
nil,
NSStringFromClass(AppDelegate.self)
)
要更改 UIApplication class,请用 NSStringFromClass(MobileUIApplication.self)
替换该公式中的 nil
。
但是,如果您的 仅 目的是将 UIApplication subclass 替换为共享应用程序实例,则有一个更简单的方法:在 Info.plist,添加 "Principal class" 键并将其值设置为您的 UIApplication subclass 的字符串名称,并标记您对该 subclass 的声明@objc(...)
属性赋予它相同的 Objective-C 名称。
编辑 此问题现已在 Swift 4.2 中解决。 CommandLine.unsafeArgv
现在有了正确的签名,可以轻松调用 UIApplicationMain
:
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv,
nil, NSStringFromClass(AppDelegate.self)
)
我们有一个自定义的 UIApplication 对象,所以我们的 main.swift 是
import Foundation
import UIKit
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(MobileUIApplication), NSStringFromClass(AppDelegate))
这在 Xcode 8 beta 5 中不起作用,所以我们使用了这个
//TODO Swift 3 workaround? https://forums.developer.apple.com/thread/46405
UIApplicationMain( Process.argc, UnsafeMutablePointer<UnsafeMutablePointer<CChar>>(Process.unsafeArgv), nil, NSStringFromClass(AppDelegate.self))
在 Xcode 8 beta 6 上,我们得到 使用未解析的标识符 'Process'
我们需要在 Xcode 8 beta 6/Swift 3 中做什么来定义 UIApplicationMain?
似乎 Process
在 beta 6 中已重命名为 CommandLine
。
但是CommandLine.unsafeArgv
的类型与UIApplication
的第二个参数不匹配,所以你可能需要这样写:
CommandLine.unsafeArgv.withMemoryRebound(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc)) {argv in
_ = UIApplicationMain(CommandLine.argc, argv, NSStringFromClass(MobileUIApplication.self), NSStringFromClass(AppDelegate.self))
}
(更新)这种不匹配应该被视为一个错误。一般情况下,发现"this-should-not-be"的时候最好发一个bug report,比如beta 5的第三个参数,希望这个"bug"能尽快修复
如果您只想指定自定义 UIApplication class,为什么不使用 Info.plist?
NSPrincipalClass | String | $(PRODUCT_MODULE_NAME).MobileUIApplication
(在 non-Raw Keys/Values 视图中显示为 "Principal class"。)
在您的 Info.plist 中有了这个,您就可以使用 @UIApplicationMain
的正常方式使用您的 MobileUIApplication
。
(添加)Header 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.
我是这样写的:
UIApplicationMain(
CommandLine.argc,
UnsafeMutableRawPointer(CommandLine.unsafeArgv)
.bindMemory(
to: UnsafeMutablePointer<Int8>.self,
capacity: Int(CommandLine.argc)),
nil,
NSStringFromClass(AppDelegate.self)
)
要更改 UIApplication class,请用 NSStringFromClass(MobileUIApplication.self)
替换该公式中的 nil
。
但是,如果您的 仅 目的是将 UIApplication subclass 替换为共享应用程序实例,则有一个更简单的方法:在 Info.plist,添加 "Principal class" 键并将其值设置为您的 UIApplication subclass 的字符串名称,并标记您对该 subclass 的声明@objc(...)
属性赋予它相同的 Objective-C 名称。
编辑 此问题现已在 Swift 4.2 中解决。 CommandLine.unsafeArgv
现在有了正确的签名,可以轻松调用 UIApplicationMain
:
UIApplicationMain(
CommandLine.argc, CommandLine.unsafeArgv,
nil, NSStringFromClass(AppDelegate.self)
)