是否可以在 SwiftUI 中提供服务并将数据推送到视图并更新 UI?

Is it possible to have a Service in SwiftUI and push data to a View and update the UI?

我有一个服务文件,可以获取数据并将数据发送到后端。是否可以将推送数据从服务推送到视图并让 UI 像 @State 一样获取更改(不像全局变量)。

@EnviornmentObject 无法以只读方式工作 全局变量不工作,因为不通知 UI

import SwiftUI
import SocketIO
import Combine

let manager = SocketManager(socketURL: URL(string: "http://localhost:30000/ios")!, config: [.log(true), .compress])
let socket = manager.defaultSocket

class Socket: BindableObject {
    let didChange = PassthroughSubject<Socket,Never>()
    var sliderValue: Float = 6 {
        willSet {
            print(newValue)
            didChange.send(self)
        }
    }
    static let sharedInstance = Socket()
    init() {

        socket.on(clientEvent: .connect) {data, ack in
            print("socket connected")
            self.sliderValue = 8 
        }

    }


    func establishConnection() {
        socket.connect()
    }

    func closeConnection() {
        socket.disconnect()
    }
}

主页视图:

import SwiftUI

struct HomeView : View {
    @EnvironmentObject var socketData: Socket

    var body: some View {
        VStack {
            Text("Hello World")
            Slider(value: $socketData.sliderValue, from: 0.0, through: 10.0)
            Text(String(socketData.sliderValue))
        }
    }
}

您可以让您的 Socket 具有 messagePublisher,以便使用传入消息更新 child 视图。

class Socket {
    static let sharedInstance = Socket()
    public let messagePublisher = PassthroughSubject<Message, Never>()
    init() {

      socket.on(clientEvent: .connect) {data, ack in
          print("socket connected")
          let message = data as! Message
          messagePublisher.send(message)
      }

    }
}

然后让您的 children 像这样订阅收到的消息:

Socket.sharedInstance.assign(to: \.message, on: messageModel)

其中 MessageModel 符合 BindableObject 协议

我仍然遇到无法从套接字获取数据但正常字符串工作的问题我将为这个问题打开一个新问题:

我确实不得不使用 didSet 这里是代码:

let manager = SocketManager(socketURL: URL(string: "http://localhost:30000/ios")!, config: [.log(true), .compress])
let socket = manager.defaultSocket


class Socket: BindableObject {
    let didChange = PassthroughSubject<Socket,Never>()
    var days: String = "Loading..." {
        didSet {
            didChange.send(self)
        }
    }
    static let sharedInstance = Socket()
    init() {

        socket.on(clientEvent: .connect) {data, ack in
            print("socket connected")
        }
        socket.on("dailyWeather") {data, ack in
            print("just a test")
            self.days = "cur"
        }
    }


    func establishConnection() {
        socket.connect()
    }

    func closeConnection() {
        socket.disconnect()
    }
}