App Delegate 访问环境对象
App Delegate Accessing Environment Object
我在 class 中有一个变量(描述戏剧的标签),我需要在我的视图之间传递它,这是我通过 @EnvironmentObject 状态完成的。当更改该标签的函数(与变量在同一 class 中)被一个视图调用时,该变量将在其他视图中更新。但是,当触发通知时,AppDelegate 也会调用该函数。目前,我已经得到 class 包含在 AppDelegate 中声明为新实例的标签,这导致 view/struct.
中的变量没有变化
是否可以让 AppDeleagte 访问环境对象(例如,通过 AppDelegate().environmentobject(myClass),如果可以,在哪里?)或者有更好的方法吗?
简化代码:
Class 其中包含播放列表标签和更改播放列表和标签的函数
class MusicManager: NSObject, ObservableObject {
var playlistLabel: String = ""
func playPlaylistNow(chosenPlaylist: String?) {
playlistLabel = "Playlist: \(chosenPlaylist!)"
}
}
显示标签的主页视图
struct HomeView: View {
@EnvironmentObject var musicManager: MusicManager
var body: some View {
Text(musicManager.playlistLabel)
}
}
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, AVAudioPlayerDelegate {
var musicManager: MusicManager = MusicManager()
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
var playlistName: String = ""
if let userInfo = notification.userInfo {
playlistName = userInfo["soundName"] as! String
}
musicPlayerManager.playPlaylist(chosenPlaylist: playlistName)
}
}
这是可能的方法。假设您的AppDelegate
有属性喜欢
var musicManager: MusicManager?
在你的 SceneDelegate
中,我想你创建 HomeView
,你可以有以下代码
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let musicManager = MusicManager()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
addDelegate.musicManager = musicManager
}
let contentView = HomeView().environmentObject(musicManager)
...
因此 AppDelegate
和 HomeView
都可以访问 MusicManager
.
的相同实例
反之亦然
...
var musicManager: MusicManager?
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
musicManager = addDelegate.musicManager
}
let contentView = HomeView().environmentObject(musicManager ?? MusicManager())
...
取决于哪个更可取。
解决此类问题的更好方法,其中您需要使同一实例全局可用,您应该使用 Singleton
设计模式。此外,根据最佳编码实践,我们应该避免使用多个职责和变量重载 AppDelegate。通过划分责任来解耦你的代码总是更好的。
class MusicManager: NSObject, ObservableObject {
let sharedMusicManager = MusicManager()
var playlistLabel: String = ""
private init() {}
func playPlaylistNow(chosenPlaylist: String?) {
playlistLabel = "Playlist: \(chosenPlaylist!)"
}
}
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, AVAudioPlayerDelegate {
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
var playlistName: String = ""
if let userInfo = notification.userInfo {
playlistName = userInfo["soundName"] as! String
}
sharedMusicManager.playPlaylist(chosenPlaylist: playlistName)
}
}
同样,您可以从其他视图更新变量。保留 private init()
将确保不会再创建该 class 的其他实例。此外,它将始终显示最新的值。
我在 class 中有一个变量(描述戏剧的标签),我需要在我的视图之间传递它,这是我通过 @EnvironmentObject 状态完成的。当更改该标签的函数(与变量在同一 class 中)被一个视图调用时,该变量将在其他视图中更新。但是,当触发通知时,AppDelegate 也会调用该函数。目前,我已经得到 class 包含在 AppDelegate 中声明为新实例的标签,这导致 view/struct.
中的变量没有变化是否可以让 AppDeleagte 访问环境对象(例如,通过 AppDelegate().environmentobject(myClass),如果可以,在哪里?)或者有更好的方法吗?
简化代码:
Class 其中包含播放列表标签和更改播放列表和标签的函数
class MusicManager: NSObject, ObservableObject {
var playlistLabel: String = ""
func playPlaylistNow(chosenPlaylist: String?) {
playlistLabel = "Playlist: \(chosenPlaylist!)"
}
}
显示标签的主页视图
struct HomeView: View {
@EnvironmentObject var musicManager: MusicManager
var body: some View {
Text(musicManager.playlistLabel)
}
}
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, AVAudioPlayerDelegate {
var musicManager: MusicManager = MusicManager()
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
var playlistName: String = ""
if let userInfo = notification.userInfo {
playlistName = userInfo["soundName"] as! String
}
musicPlayerManager.playPlaylist(chosenPlaylist: playlistName)
}
}
这是可能的方法。假设您的AppDelegate
有属性喜欢
var musicManager: MusicManager?
在你的 SceneDelegate
中,我想你创建 HomeView
,你可以有以下代码
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let musicManager = MusicManager()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
addDelegate.musicManager = musicManager
}
let contentView = HomeView().environmentObject(musicManager)
...
因此 AppDelegate
和 HomeView
都可以访问 MusicManager
.
反之亦然
...
var musicManager: MusicManager?
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
musicManager = addDelegate.musicManager
}
let contentView = HomeView().environmentObject(musicManager ?? MusicManager())
...
取决于哪个更可取。
解决此类问题的更好方法,其中您需要使同一实例全局可用,您应该使用 Singleton
设计模式。此外,根据最佳编码实践,我们应该避免使用多个职责和变量重载 AppDelegate。通过划分责任来解耦你的代码总是更好的。
class MusicManager: NSObject, ObservableObject {
let sharedMusicManager = MusicManager()
var playlistLabel: String = ""
private init() {}
func playPlaylistNow(chosenPlaylist: String?) {
playlistLabel = "Playlist: \(chosenPlaylist!)"
}
}
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, AVAudioPlayerDelegate {
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
var playlistName: String = ""
if let userInfo = notification.userInfo {
playlistName = userInfo["soundName"] as! String
}
sharedMusicManager.playPlaylist(chosenPlaylist: playlistName)
}
}
同样,您可以从其他视图更新变量。保留 private init()
将确保不会再创建该 class 的其他实例。此外,它将始终显示最新的值。