Skip to content

Commit a8f4773

Browse files
committed
Version 5.2.5
1 parent 2f56c31 commit a8f4773

11 files changed

Lines changed: 793 additions & 3 deletions

File tree

Packages/STDemos_iOS/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Packages/STDemos_iOS/Package.resolved

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Packages/STDemos_iOS/Package.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ let package = Package(
2323
.package(url: "https://github.com/core-plot/core-plot", branch: "release-2.4"),
2424
.package(url: "https://github.com/scalessec/Toast-Swift", branch: "master"),
2525
.package(url: "https://github.com/JonasGessner/JGProgressHUD.git", from: Version(2, 2, 0)),
26-
.package(url: "https://github.com/danielgindi/Charts.git", from: Version(5, 1, 0))
26+
.package(url: "https://github.com/danielgindi/Charts.git", from: Version(5, 1, 0)),
27+
.package(url: "https://github.com/emqx/CocoaMQTT.git", branch: "master")
2728

2829
],
2930
targets: [
@@ -38,7 +39,8 @@ let package = Package(
3839
.product(name: "CorePlot", package: "core-plot"),
3940
.product(name: "Toast", package: "Toast-Swift"),
4041
.product(name: "JGProgressHUD", package: "JGProgressHUD"),
41-
.product(name: "DGCharts", package: "Charts")
42+
.product(name: "DGCharts", package: "Charts"),
43+
.product(name: "CocoaMQTT", package: "CocoaMQTT")
4244
],
4345
resources: [
4446
.copy("Resources/Assets.xcassets"),
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// CloudMQTTDelegate.swift
3+
//
4+
// Copyright (c) 2025 STMicroelectronics.
5+
// All rights reserved.
6+
//
7+
// This software is licensed under terms that can be found in the LICENSE file in
8+
// the root directory of this software component.
9+
// If no LICENSE file comes with this software, it is provided AS-IS.
10+
//
11+
12+
protocol CloudMQTTDelegate: AnyObject {
13+
14+
func load()
15+
16+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// CloudMQTTView.swift
3+
//
4+
// Copyright (c) 2025 STMicroelectronics.
5+
// All rights reserved.
6+
//
7+
// This software is licensed under terms that can be found in the LICENSE file in
8+
// the root directory of this software component.
9+
// If no LICENSE file comes with this software, it is provided AS-IS.
10+
//
11+
12+
import SwiftUI
13+
import Foundation
14+
import STUI
15+
16+
public struct CloudMQTTMainView: View {
17+
18+
@State private var brokerUrl: String = ""
19+
@State private var port: String = ""
20+
@State private var userName: String = ""
21+
@State private var password: String = ""
22+
@State private var deviceID: String = ""
23+
24+
init() {
25+
let appearance = UITabBarAppearance()
26+
appearance.configureWithOpaqueBackground() // Prevents transparent/blur effect
27+
appearance.backgroundColor = ColorLayout.primary.auto // Your desired background color
28+
29+
UITabBar.appearance().standardAppearance = appearance
30+
UITabBar.appearance().scrollEdgeAppearance = appearance
31+
32+
UITabBar.appearance().backgroundColor = ColorLayout.primary.auto
33+
UITabBar.appearance().unselectedItemTintColor = UIColor.gray
34+
}
35+
36+
public var body: some View {
37+
// TabView (selection: $model.tabViewSelectedIndex){
38+
TabView() {
39+
// CloudMQTTAppConfigView()
40+
// .tag(0)
41+
// .tabItem {
42+
// Label {
43+
// Text("App Config")
44+
// } icon: {
45+
// ImageLayout.SUICommon.builcConfig
46+
// }
47+
// }
48+
49+
// CloudMQTTDevUploadView()
50+
// .tag(1)
51+
// .tabItem {
52+
// Label {
53+
// Text("Dev Upload")
54+
// } icon: {
55+
// ImageLayout.SUICommon.cloudUpload
56+
// }
57+
//
58+
// }
59+
}
60+
.tint(.white)
61+
// .environmentObject(model)
62+
}
63+
}
64+
65+
#Preview {
66+
LegacyView()
67+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// CloudMQTTPresenter.swift
3+
//
4+
// Copyright (c) 2025 STMicroelectronics.
5+
// All rights reserved.
6+
//
7+
// This software is licensed under terms that can be found in the LICENSE file in
8+
// the root directory of this software component.
9+
// If no LICENSE file comes with this software, it is provided AS-IS.
10+
//
11+
12+
import STBlueSDK
13+
import STCore
14+
15+
final class CloudMQTTPresenter: DemoPresenter<CloudMQTTViewController> {
16+
}
17+
18+
// MARK: - CarryPositionViewControllerDelegate
19+
extension CloudMQTTPresenter: CloudMQTTDelegate {
20+
21+
func load() {
22+
demo = .cloudMqtt
23+
24+
demoFeatures = param.node.characteristics.features(with: Demo.cloudMqtt.features)
25+
26+
// if let feature = param.node.characteristics.first(with: BatteryFeature.self) {
27+
// BlueManager.shared.enableNotifications(for: param.node, feature: feature)
28+
// }
29+
//
30+
view.configureView()
31+
32+
view.presentSwiftUIView(CloudMQTTConfigurationView(node: param.node))
33+
}
34+
35+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// CloudMQTTViewController.swift
3+
//
4+
// Copyright (c) 2025 STMicroelectronics.
5+
// All rights reserved.
6+
//
7+
// This software is licensed under terms that can be found in the LICENSE file in
8+
// the root directory of this software component.
9+
// If no LICENSE file comes with this software, it is provided AS-IS.
10+
//
11+
12+
import Foundation
13+
import STBlueSDK
14+
15+
final class CloudMQTTViewController: DemoNodeNoViewController<CloudMQTTDelegate> {
16+
17+
override func configure() {
18+
super.configure()
19+
}
20+
21+
override func viewDidLoad() {
22+
super.viewDidLoad()
23+
24+
// title = Demo.cloudMqtt.title
25+
title = ""
26+
27+
presenter.load()
28+
}
29+
30+
override func configureView() {
31+
super.configureView()
32+
33+
// if let presenter = presenter as? CloudMQTTPresenter {
34+
// let node = presenter.param.node
35+
// presentSwiftUIView(CloudMQTTAppConfigView(node: node))
36+
// }
37+
//
38+
}
39+
40+
override func manager(_ manager: BlueManager,
41+
didUpdateValueFor node: Node,
42+
feature: Feature,
43+
sample: AnyFeatureSample?) {
44+
45+
super.manager(manager, didUpdateValueFor: node, feature: feature, sample: sample)
46+
47+
48+
DispatchQueue.main.async { [weak self] in
49+
print(sample)
50+
}
51+
}
52+
53+
54+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//
2+
// CloudMQTTViewModel.swift
3+
//
4+
// Copyright (c) 2025 STMicroelectronics.
5+
// All rights reserved.
6+
//
7+
// This software is licensed under terms that can be found in the LICENSE file in
8+
// the root directory of this software component.
9+
// If no LICENSE file comes with this software, it is provided AS-IS.
10+
//
11+
12+
import CocoaMQTT
13+
import Foundation
14+
import STBlueSDK
15+
16+
// MARK: - MQTTSession
17+
public struct MQTTSession: Codable {
18+
public var hostUrl: String
19+
public var port: String
20+
public var username: String?
21+
public var password: String?
22+
public var deviceID: String
23+
}
24+
25+
// MARK: - MQTTFeature
26+
public struct MQTTFeature: Identifiable {
27+
public let id = UUID()
28+
public let feature: Feature
29+
public var enabled: Bool
30+
}
31+
32+
class CloudMQTTViewModel: ObservableObject {
33+
var mqtt: CocoaMQTT?
34+
public var session: MQTTSession?
35+
public var onConnect: (() -> Void)?
36+
public var onConnectionError: ((String) -> Void)?
37+
@Published public var currentMessagePayload: String = "---"
38+
@Published public var currentTopic: String = "---"
39+
40+
func saveMqttSessionConfigurationAndConnect(_ hostUrl: String,
41+
_ port: String,
42+
_ username: String?,
43+
_ password: String?,
44+
_ deviceID: String) {
45+
46+
let mqttSession = MQTTSession(
47+
hostUrl: hostUrl,
48+
port: port,
49+
username: username,
50+
password: password,
51+
deviceID: deviceID)
52+
53+
let encoder = JSONEncoder()
54+
if let encoded = try? encoder.encode(mqttSession) {
55+
UserDefaults.standard.set(encoded, forKey: "MqttConfiguration")
56+
}
57+
58+
session = mqttSession
59+
60+
connect(mqttSession)
61+
}
62+
63+
func loadMqttSessionConfiguration() -> MQTTSession? {
64+
if let savedData = UserDefaults.standard.data(forKey: "MqttConfiguration") {
65+
let decoder = JSONDecoder()
66+
if let loadedConfiguration = try? decoder.decode(MQTTSession.self, from: savedData) {
67+
return loadedConfiguration
68+
}
69+
}
70+
return nil
71+
}
72+
73+
private func connect(_ session: MQTTSession) {
74+
let clientID = "iOSClient-\(UUID().uuidString.prefix(6))"
75+
76+
if let numberPort = UInt16(session.port) {
77+
mqtt = CocoaMQTT(clientID: clientID, host: session.hostUrl, port: numberPort)
78+
mqtt?.username = session.username
79+
mqtt?.password = session.password
80+
mqtt?.delegate = self
81+
mqtt?.connect()
82+
} else {
83+
print("Conversion failed: string is not a valid UInt16")
84+
}
85+
}
86+
87+
public func subscribe(to topic: String) {
88+
mqtt?.subscribe(topic)
89+
}
90+
91+
public func unsubscribe(to topic: String) {
92+
mqtt?.unsubscribe(topic)
93+
}
94+
95+
public func publish(message: String, to topic: String) {
96+
mqtt?.publish(topic, withString: message)
97+
}
98+
99+
public func isConnStateConnected() -> Bool {
100+
guard let mqtt = mqtt else { return false }
101+
return mqtt.connState == .connected
102+
}
103+
}
104+
105+
extension CloudMQTTViewModel: CocoaMQTTDelegate {
106+
public func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
107+
if ack == .accept {
108+
onConnect?()
109+
print("✅ MQTT connected successfully!")
110+
} else {
111+
onConnectionError?("❌ MQTT connection failed: \(ack)")
112+
print("\(ack)")
113+
}
114+
}
115+
116+
public func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
117+
print("Message published: \(message.string ?? "")")
118+
}
119+
120+
public func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
121+
print("Received message: \(message.string ?? "")")
122+
}
123+
124+
public func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
125+
print("didPublishAck")
126+
}
127+
128+
public func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
129+
print("didSubscribeTopics")
130+
}
131+
132+
public func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
133+
print("didUnsubscribeTopics")
134+
}
135+
136+
public func mqttDidPing(_ mqtt: CocoaMQTT) {
137+
print("mqttDidPing")
138+
}
139+
140+
public func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
141+
print("mqttDidReceivePong")
142+
}
143+
144+
public func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: (any Error)?) {
145+
print("mqttDidDisconnect with error: \(err.debugDescription)")
146+
}
147+
}

0 commit comments

Comments
 (0)