Как получить доступ к глобальному объекту среды в классе?

#swiftui #environmentobject

#swiftui #environmentobject

Вопрос:

У меня есть класс, которому необходимо обновить глобальный объект среды. Я могу передавать этот объект среды между своими структурами весь день, но как мне разрешить объекту класса обращаться к той же переменной?

 import SwiftUI

class Global: ObservableObject
{
    @Published var num = 10
}

class MyClass:ObservableObject
{
    @Published var mode = 1
    @EnvironmentObject var global: Global

    func updateMode()
    {
        self.mode  = 1
        global.num  = 1
    }
}

@main
struct MyApp: App
{
    let settings = Global()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(settings)
            }
    }
}

struct ContentView: View
{
    @EnvironmentObject var global: Global
    @ObservedObject var myClass = MyClass()
    
    var body: some View
    {
        VStack
        {
            Text("Setting (global.num)")
            Text("Mode (myClass.mode)")

            Button("Click Me", action: {myClass.updateMode()})
        }
        .padding()
    }
}
 

Следующий код выдает ошибку:

Неустранимая ошибка: не найден ObservableObject типа Global. View.environmentObject(_:) для глобального, возможно, отсутствует предок этого представления.

Я мог бы передать глобальный объект в MyClass.UpdateMode, но тогда он не кажется очень глобальным на данный момент? Я бы подумал, что должен быть лучший способ.

Ответ №1:

Возможный подход заключается в том, чтобы сделать его общим (и не использовать @EnvironmentObject нигде за пределами SwiftUI view — он не предназначен для этого):

 class Global: ObservableObject
{
    static let shared = Global()

    @Published var num = 10
}

class MyClass:ObservableObject
{
    @Published var mode = 1
    let global = Global.shared    // << here !!

// ...
}

@main
struct MyApp: App
{
    @StateObject var settings = Global.shared  // << same !!
// ...
}
 

Комментарии:

1. Спасибо. Это уже стало одним из моих любимых решений goto.

2. Просто обратите внимание, что вам нужно будет привязать к вашим значениям @Published следующим образом: $settings.num

3. хорошее решение для управления глобальными состояниями!

4. Очень хорошее решение для управления глобальными переменными. Это решение облегчило мне жизнь