Мне интересно, есть ли способ решить, как ViewModel выполняется до AppDelegate в моем приложении macOS.
Предположим, у меня есть эти файлы:
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
UserDefaults.shared.register(defaults: [ // <--- breakpoint 1
"userDefaultItem1" : false,
"userDefaultItem2" : 0
])
}
}
@main
struct AppName: App {
@NSApplicationDelegateAdaptor(AppDelegate.self)
private var appDelegate // <--- breakpoint 2
@StateObject
var vm = ViewModel() // <--- breakpoint 3
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(vm)
}
}
}
Когда я запускаю приложение, оно достигает точки останова 2, затем точки останова 3, затем точки останова 1.
В результате ни один из UserDefaults не зарегистрирован до доступа в ViewModel, и происходит сбой.
Это то, что должно произойти, и хотя использование AppDelegates не требуется, в устаревшем коде есть использование, которое теперь перенесено в SwiftUI.
если вы хотите убедиться, что что-то обрабатывается до того, как AppDelegate вызовет свои методы делегата, вы также можете поместить UserDefaults
код в init
вашего AppDelegate. Или также возможно, просто переместите код на applicationWillFinishLaunching
, который вызывается ранее.
init() { .. }
будет работать, потому что NSObjects всегда следуют шаблону alloc-init. Таким образом, init вызывается первым (вторым после alloc) еще до вызова любого метода делегата.
Кроме того, когда ваше приложение дает сбой из-за отсутствия UserDefaults, стоит проверить, что происходит, когда UserDefaults вообще не используются. Это заставит вас закодировать резервный код, а затем вы примените UserDefaults к этим подготовленным резервным свойствам, «обновив» их, и продолжите оттуда. Это гарантирует, что когда пользователь откроет ваше приложение в первый раз, где, скорее всего, нет установленных UserDefaults, оно не выйдет из строя.
Вкратце: использование UserDefaults без отката — это проблема шаблона проектирования. Вы всегда должны предоставлять оценку UserDefaults перед применением, а иногда даже перед их изменением, потому что пользователи могут даже стереть их или иным образом манипулировать ими на Mac.
PS: ваша ViewModel, скорее всего, вызывается через запись в Storyboard
или основной наконечник и соответственно помечается Info.plist
для этого.
еще один момент, о котором следует подумать, это то, что когда этот конкретный UserDefault необходим для ViewModel, тогда также стоит вспомнить и оценить их в init() ViewModel вместо AppDelegate.