Xcode 12引入了使用SwiftUI从上到下编写整个应用程序的选项,而不仅仅是视图。尽管我们仍然可能需要在某些地方混合和匹配使用UIKit构建的SwiftUI视图,但现在我们可以开始使用一个简单的APP结构体定义来构建一个新的基于SwiftUI的应用:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
RootView()
}
}
}
然而,尽管上面的应用程序API非常简洁和轻量级,但它不支持与UIKit对应的UIApplicationDelegate一样的功能和灵活性,而UIKit是iOS和tvOS应用程序之前的入口点:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...
}
但这里有一个好消息:我们实际上仍然可以使用一个老式的AppDelegate,即使是在构建一个基于SwiftUI的应用程序时,通过使用UIApplicationDelegateAdapter属性包装器。我们所要做的就是在我们的应用结构的任何地方声明这样一个属性,使用任何我们想要的名称,然后SwiftUI会自动检测它,并使用指定的类型作为应用的委托:
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
...
}
}
很酷的!值得记住的是,如果我们正在以这种方式调整一个现有的应用程序委托,我们将需要从它那里删除@UIApplicationMain属性(作为一个程序不能有两个主要入口点):
class AppDelegate: UIResponder, UIApplicationDelegate {
...
}
最后,如果我们希望使用应用委托来处理url(例如深层链接),那么SwiftUI现在也提供了一个内置的API来完成这一任务。要使用它,我们只需要将onOpenURL修饰符应用到我们的层次结构中的任何视图,例如我们应用的根视图:
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
RootView().onOpenURL { url in
// URL handling
}
}
}
}
SwiftUI与UIKit和AppKit的强大互操作性无疑是其主要优势之一,因为它使我们能够以一种更零散的方式来采用它——我很高兴看到这一趋势在App和UIApplicationDelegate上继续发展。