如何在视图和 类 中使用全局变量?
How use global Variables in views and classes?
我正在尝试通过外部库获取设备的温度,
当屏幕启动时温度值为“----”当设备通过委托给我温度结果时我想用要保存在 class 中的值更新视图(ts28bControllerDelegate) 温度值并在视图中检索它以显示它,因为我的代码始终保持空白 (Text ("\ (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)
}
}
谁能帮我理解一下?
谢谢!
关于您评论中的(第二个)问题,
这里有一些代码显示了一种从“发送”值的方法
class(不一定是视图)并在视图中接收该值。
您可以在“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")
}
}
}
}
我正在尝试通过外部库获取设备的温度,
当屏幕启动时温度值为“----”当设备通过委托给我温度结果时我想用要保存在 class 中的值更新视图(ts28bControllerDelegate) 温度值并在视图中检索它以显示它,因为我的代码始终保持空白 (Text ("\ (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)
}
}
谁能帮我理解一下?
谢谢!
关于您评论中的(第二个)问题, 这里有一些代码显示了一种从“发送”值的方法 class(不一定是视图)并在视图中接收该值。
您可以在“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")
}
}
}
}