首页 > 解决方案 > 如何在视图和类中使用全局变量?

问题描述

我正在尝试通过外部库来获取设备的温度,

当屏幕启动时,温度值为“----”当设备通过委托给我温度结果时,我想用要保存在类 (ts28bControllerDelegate) 中的值更新视图,温度值和在视图中检索它以显示它,因为我的代码始终保持空白(文本(“\(global.temp)”))

//
//  TakeTemperatureTS28BUIView.swift
//  aidicarev3UI
//
//  Created by Laura Ramirez on 26/08/21.
//

import SwiftUI

struct ContentView2: View {
    @State private var index = 1
    @EnvironmentObject private var global: GlobalTs28b

    init() {
        Theme.navigationBarColors(background: .white , titleColor: UIColor( red: CGFloat(92/255.0), green: CGFloat(203/255.0), blue: CGFloat(207/255.0), alpha: CGFloat(1.0)))
    }

    var body: some View {
        VStack{
            ScrollView{
                VStack{
                    VStack(){
                        Image("bluetooth-5")
                            .resizable()
                            .frame(width: UIScreen.main.bounds.width / 2, height: 140.0)
                            .padding()
                        Text("temp15Tittle")
                            .modifier(Fonts(fontName: .bold, size: 16))
                            .foregroundColor(Color("blueColor"))
                            .fixedSize(horizontal: false, vertical: true)
                            .padding(.top,30)
                    }
                    Divider()
                        .padding()
                    Text("temp1Tittle")
                        .frame(maxWidth: .infinity, alignment: .center)
                        .modifier(Fonts(fontName: .bold, size: 16))
                        .foregroundColor(Color("blackColor"))
                        .fixedSize(horizontal: false, vertical: true)
                        .padding(.top,10)
                        .padding()
                    HStack{
                        Text("\(global.temp)")
                            .autocapitalization(.none)
                            .foregroundColor(Color("blackColor"))
                            .padding(.leading,20)
                        Text("°C")
                            .modifier(Fonts(fontName: .bold, size: 16))
                            .foregroundColor(Color("blackColor"))
                            .padding()
                            
                    }
                    .foregroundColor(Color("blackColor"))
                    .overlay(RoundedRectangle(cornerRadius: 40).stroke(Color("grayColor"), lineWidth: 1)).background(RoundedRectangle(cornerRadius: 40).fill(Color("whiteColor")))
                    .padding(.trailing,60)
                    .padding(.leading,60)
                    
                    Button(action:{
                        SaveTemp()
                    }){
                        HStack{
                            Text("temp16Tittle")
                            .foregroundColor(Color("whiteColor"))
                            .modifier(Fonts(fontName: .bold, size: 16))
                            .frame(width: 150 , height: 10, alignment: .center)
                            }
                        .foregroundColor(Color("whiteColor"))
                        .modifier(Fonts(fontName: .medium, size: 16))
                        .padding()
                        .background(Color("blueColor"))
                        .cornerRadius(80)
                        .padding(.top,30)
                    }
                    
                }
            }
                .padding()
                .padding()
                Spacer()
                MenuMain(index: self.$index)
            }
            .background(Color("backgroundColor"))
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .principal) {
                    VStack {
                        Text("temp7Tittle").font(.headline)
                            .modifier(Fonts(fontName: .light, size: 18))
                            .foregroundColor(Color("grayDarkColor"))
                            .fixedSize(horizontal: false, vertical: true)
                            .frame(maxWidth: .infinity, alignment: .leading)
                        
                    }
                }
            }
            .onAppear {
                iHealthAuthTS28B()
            }
            .onDisappear {
                //desconectar dispositivos
            }
        }
}

struct TakeTemperatureTS28BUIView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            TakeTemperatureTS28BUIView()
            .navigationBarTitleDisplayMode(.inline)
            .accentColor(.black)
            .toolbar { // <2>
                ToolbarItem(placement: .principal) { // <3>
                    HStack {
                        Text("temp7Tittle").font(.headline)
                            .modifier(Fonts(fontName: .light, size: 18))
                            .foregroundColor(Color("grayDarkColor"))
                            .fixedSize(horizontal: false, vertical: true)
                            .frame(maxWidth: .infinity, alignment: .leading)
                        Spacer()
                    }
                    
                }
            }
        }
    }
}

struct TakeTemperatureTS28BUIView: View {
    @StateObject private var global = GlobalTs28b()
    var body: some View {
        ContentView2()
            .environmentObject(global)
    }
}


func iHealthAuthTS28B() {
    print("ENTRA EN AUTENTIFICACION DE IHEALTH TS28B")
    let bundle = Bundle.main
    let path = bundle.path(forResource: "com_aidicare_aidicarev3UI_ios", ofType: ".pem")
    let cert = NSData(contentsOfFile: path!)
    print(cert as Any)
    
    let delegate = ts28bControllerDelegate.init()
    
    IHSDKCloudUser.commandGetSDKUserInstance().commandSDKUserValidation(withLicense: cert as Data?, userDeviceAccess: {
        devices in
        print("--devices--")
        print(devices as Any)
    }, userValidationSuccess: { UserAuthenResult in
        print("--UserAuthenResult--")
        print(UserAuthenResult)
        delegate.StartSync()
    }, disposeErrorBlock: { UserAuthenResult in
        print("--UserAuthenResult--")
        print(UserAuthenResult)
        switch (UserAuthenResult) {
            case UserAuthen_InputError:
                print("error")
                break;
            case UserAuthen_CertificateExpired:
                print("certiificado expirado")
                break;
            case UserAuthen_InvalidCertificate:
                print("certificado no valido")
                break;
            default:
                break;
        }
    })
}

func Sincroniza(){
    print("ENTRA EN TOMA DE TEMPERATURA TS28B")
    iHealthAuthTS28B()
}

func SaveTemp(){
    print("ENTRA EN GUARDAR DE TEMPERATURA")
    let global = GlobalTs28b()
    print("VALOR: ", global.temp)
}
class GlobalTs28b: ObservableObject {
    @Published var temp: String = "----"
    @Published var state: String = "----"
}

class ts28bControllerDelegate: NSObject, TS28BControllerDelegate {
    var myCentralManager: CBCentralManager = CBCentralManager()
    var controllerTS28B: TS28BController = TS28BController()
    let user: HealthUser = HealthUser()
    var device: TS28B = TS28B()
    var connectedDevice: TS28B?
    
    var global = GlobalTs28b()
    
    override init() {
        super.init()
        print("ENTRA EN StartDiscoverTS28B")
        controllerTS28B = TS28BController.shared()
        controllerTS28B.delegate = self
    }
    
    func StartSync(){
        print("empieza StartSync")
        controllerTS28B.startScan()
    }
    
    // MARK: - delegate

    public func controller(_ controller: TS28BController?, didDiscoverDevice device: TS28B?) {
        print("The agent of the device is found")
        connectedDevice = device

        controller?.connectDevice(connectedDevice)

        if let device = device {
            print("DiscoverDevice: \(device)")
        }
    }

    public func controller(_ controller: TS28BController?, didConnectSuccessDevice device: TS28B?) {
        print("Successfully connected agent")
        connectedDevice = device
        if let device = device {
            print("DiscoverDevice: \(device)")
        }
    }

    public func controller(_ controller: TS28BController?, didConnectFailDevice device: TS28B?) {
        print("Proxy failed to connect")
        //    self.recordTextView.text = @"连接失败";
    }

    public func controller(_ controller: TS28BController?, didDisconnectDevice device: TS28B?) {
        print("Disconnected proxy")
        //    self.recordTextView.text = @"连接断开";

        if let device = device {
            print("DisConnectDevice: \(device) ")
        }
    }

    public func controller(_ controller: TS28BController?, device: TS28B?, didUpdateTemperature value: Float, temperatureUnit unit: TemperatureUnit, measure date: Date?, measureLocation type: TemperatureType) {
        print("Temperature UNIDAD:", unit)
        print("Temperature:", value)
        
        let valueFinal = ((value - 32) * 5/9)
        
        let stringFloat =  String(describing: valueFinal)
        global.temp = stringFloat
        print("centigadros:", global.temp)
         
        
    }


}


有人可以帮我理解吗?

谢谢!

标签: swiftswiftuidelegatesglobal-variables

解决方案


关于您评论中的(第二个)问题,这里有一些代码显示了一种从类“发送”值(不一定是视图)并在视图中接收该值的方法。

您可以在“ts28bControllerDelegate”中使用这种方法,在温度更新到达您的 ts28bControllerDelegate 时发送它们,并使用 .onReceive(...) 在您的视图中接收它们

public func controller(_ controller: TS28BController?, device: TS28B?, didUpdateTemperature value: Float, temperatureUnit unit: TemperatureUnit, measure date: Date?, measureLocation type: TemperatureType) {
    print("Temperature UNIDAD:", unit)
    print("Temperature:", value)
    let valueFinal = ((value - 32) * 5/9)
    let stringFloat =  String(valueFinal)
    // send a message with the temp value
    NotificationCenter.default.post(name: GlobalTs28b.globalMsg, object: stringFloat)
}



class GlobalTs28b: ObservableObject {
    @Published var temp: String = "----"
    @Published var state: String = "----"
    
    // for testing, does not have to be in this class
    static let globalMsg = Notification.Name("GlobalTs28b")
}

struct ContentView: View {
    @StateObject var global = GlobalTs28b()  // for testing
    
    var body: some View {
        NavigationView {
            VStack (spacing: 55) {
                NavigationLink("go to next view", destination: ViewTest2())
                Text(global.temp).foregroundColor(.red)
            }
            .onReceive(NotificationCenter.default.publisher(for: GlobalTs28b.globalMsg)) { msg in
                if let temp = msg.object as? String {
                    // update the StateObject with the new info, so the view will update
                    global.temp = temp
                }
            }
        }.navigationViewStyle(.stack)
    }
}

struct ViewTest2: View {
    var body: some View {
        VStack {
            Button(action: {
                // send a message to all listeners with the new temp,
                // could be used in any class such as ts28bControllerDelegate
                NotificationCenter.default.post(name: GlobalTs28b.globalMsg, object: "new temp")
            }) {
                Text("click to update temp")
            }
        }
    }
}

推荐阅读