现在AppDelegate
和SceneDelegate
已从SwiftUI中删除了,我应该将以前使用的代码放在exSceneDelegate和AppDelegate的Firebase配置中?
所以我的AppDelegate中目前有以下代码:
我现在应该在哪里放置这段代码?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseConfiguration.shared.setLoggerLevel(.min)
FirebaseApp.configure()
return true
}
答案 0 :(得分:47)
这是SwiftUI生命周期的解决方案。经过Xcode 12b / iOS 14的测试
import SwiftUI
import UIKit
// no changes in your AppDelegate class
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print(">> your code here !!")
return true
}
}
@main
struct Testing_SwiftUI2App: App {
// inject into SwiftUI life-cycle via adaptor !!!
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
答案 1 :(得分:31)
在您的 {"params":"endpoint":"import","action":"main","authenticationToken":"myToken",
"authenticationKey":"<myKey>","dataMain":[]},"tokenUsage":"requestsReadToday":"0","requestsWriteToday":"25","requestsReadInLastMinute":"1","requestsWriteInLastMinute":"0"},"tokenLimits":{"limitReadRequestsPerMinute":60,"limitReadRequestsPerDay":3000,"limitWriteRequestsPerMinute":60,"limitWriteRequestsPerDay":3000},"requestAction":"main","endpoint":"import","success":true,"customersImported":[{"CustomerID":"548745","PestRoutesCustomerID":"10109","Action":"Updated"}],"processingTime":"587 milliseconds","count":0}
中覆盖初始化程序似乎也可行:
App
答案 2 :(得分:21)
您完全不应在应用程序委托中放入这种代码,否则您最终将面临Massive App Delegate。相反,您应该考虑将代码重构为更有意义的部分,然后将正确的部分放在正确的位置。对于这种情况,您唯一需要做的就是确保一旦应用准备好并且仅执行一次,代码便会执行这些功能。因此init
方法可能很棒:
@main
struct MyApp: App {
init() {
setupFirebase()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
private extension MyApp {
func setupFirebase() {
FirebaseConfiguration.shared.setLoggerLevel(.min)
FirebaseApp.configure()
}
}
您可以拥有自己的自定义类,并将其分配为delegate
。但是请注意,它不适用于分配前发生的事件。例如:
class CustomDelegate: NSObject, UIApplicationDelegate {
static let Shared = CustomDelegate()
}
后来:
UIApplication.shared.delegate = CustomDelegate.Shared
实际上,大多数AppDelegate
方法都在观察可以手动观察而不是定义新类的通知。例如:
NotificationCenter.default.addObserver(
self,
selector: #selector(<#T##@objc method#>),
name: UIApplication.didBecomeActiveNotification,
object: nil
)
AppDelegate
包装器您可以将应用程序委托直接注入到@main
结构中:
@UIApplicationDelegateAdaptor(CustomDelegate.self) var appDelegate
AppDelegate
请记住,添加AppDelegate意味着您正在终止默认的多平台支持,并且必须手动检查平台。
答案 3 :(得分:8)
您还可以将新的ScenePhase用于AppDelegate和SceneDelegate所具有的某些代码。喜欢去后台或变得活跃。来自
struct PodcastScene: Scene {
@Environment(\.scenePhase) private var phase
var body: some Scene {
WindowGroup {
TabView {
LibraryView()
DiscoverView()
SearchView()
}
}
.onChange(of: phase) { newPhase in
switch newPhase {
case .active:
// App became active
case .inactive:
// App became inactive
case .background:
// App is running in the background
@unknown default:
// Fallback for future cases
}
}
}
}
示例功劳:https://wwdcbysundell.com/2020/building-entire-apps-with-swiftui/
答案 4 :(得分:2)
请注意,以下方法将停止跨平台支持,因此仅在计划仅针对iOS进行构建时才应使用。
在Xcode 12-beta中创建SwiftUI应用时,您仍然可以拥有AppDelegate和SceneDelegate。
您只需要确保在创建应用时为生命周期选择了正确的选项。
确保为生命周期选择 UIKit App Delegate ,您将获得一个AppDelegate和一个SceneDelegate
答案 5 :(得分:1)
我看到很多将 init
用作 didFinishLaunching
的解决方案。但是,在 didFinishLaunching
结构的 init
之后调用 App
。
相反,我们可以创建一个块来在调用 didFinishLaunching
时通知我们。这允许在 SwiftUI 世界中(而不是在 AppDelegate
中)保留更多代码。
class AppDelegate: NSObject, UIApplicationDelegate {
var didFinishLaunching: ((AppDelegate) -> Void)?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
didFinishLaunching?(self)
return true
}
}
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@ObservedObject private var applicationModel = ApplicationModel()
// `init` gets called BEFORE `didFinishLaunchingWithOptions`
init() {
// Subscribe to get a `didFinishLaunching` call
appDelegate.didFinishLaunching = { [weak applicationObject] appDelegate in
// Setup any application code...
applicationModel?.setup()
}
}
var body: some Scene {
return WindowGroup {
if applicationObject.isUserLoggedIn {
LoggedInView()
} else {
LoggedOutView()
}
}
}
}