应用程序委托访问环境对象 [英] App Delegate Accessing Environment Object

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

问题描述

我在一个类中有一个变量(描述播放的标签),我需要在各个视图之间进行传递,这是通过@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?

简化代码:

包含playlistLabel和用于更改播放列表和标签的函数的类

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)

    }

}

AppDelegate

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)

        }
    }

推荐答案

一种更好的方法来解决这类问题,在这种情况下,需要使同一实例在全局范围内可用,您应该使用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.

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

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