Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

swift - App Delegate Accessing Environment Object

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.

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?

Simplified Code:

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!)"
    }

}

Home View which displays the label

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)

        }
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is possible approach. Assuming your AppDelegate have property like

var musicManager: MusicManager?

in your SceneDelegate, where I suppose you create HomeView, you can have the following code

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)
    ...

thus both AppDelegate and HomeView have access to same instance of MusicManager.

Or vise versa

...
var musicManager: MusicManager?
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
    musicManager = addDelegate.musicManager
}
let contentView = HomeView().environmentObject(musicManager ?? MusicManager())
...

depending of what is preferable.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...