App Delegate 访问环境对象 [英] App Delegate Accessing Environment Object

查看:30
本文介绍了App Delegate 访问环境对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个类中有一个变量(一个描述游戏的标签),我需要在我的视图之间传递它,我通过@EnvironmentObject 状态来实现.当一个更改该标签的函数(与变量在同一类中)被一个视图调用时,该变量会在其他视图中更新.但是,当通知被触发时,该函数也会被 AppDelegate 调用.目前,我在 AppDelegate 中将包含标签的类声明为新实例,这导致视图/结构中的变量没有更改.

I've got a variable (a label which describes a play) within a class that I need to pass around between my views, which I do through the @EnvironmentObject state. When a function (in the same class as the variable) that changes that label gets called by one view the variable is updated in the other views. However, that function is also called by the AppDelegate when a notification is fired. At the moment, I've got the class containing the label declared as a new instance in the AppDelegate, which results in no changes to the variable in the view/struct.

是否可以让 AppDeleagte 访问环境对象(例如,通过 AppDelegate().environmentobject(myClass),如果可以,在哪里?)还是有更好的方法来做到这一点?

Is it possible to give the AppDeleagte access to the environment object (e.g. through AppDelegate().environmentobject(myClass), if so where?) or is there a better way to do this?

简化代码:

包含播放列表标签的类以及改变播放列表和标签的函数

Class which contains the playlistLabel and the the function to change the playlist and the label

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)

    }

}

应用委托

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)

        }
    }

推荐答案

解决此类问题的更好方法,其中您需要使同一个实例全局可用,您应该使用 Singleton 设计模式.此外,根据最佳编码实践,我们应该避免使用多个职责和变量重载 AppDelegate.通过划分责任来解耦代码总是更好.

A better approach to solve these kind of problems wherein you need to make the same instance globally available you should use Singleton design pattern. Also, according to best coding practices we should refrain from overloading AppDelegate with multiple responsibilities and variables. It is always better to decouple your code by dividing responsibility.

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() 将确保该类的其他实例不会再次创建.此外,它将始终显示最新的值.

Similarly you can update the variable from other views. Keeping a private init() would insure that no other instance of that class is creating again. Also, it will always display the most updated value.

这篇关于App Delegate 访问环境对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆