🐛 Fixed stupid app state updated twice
This commit is contained in:
@@ -455,17 +455,19 @@ class NetworkService {
|
||||
}
|
||||
|
||||
func connectWebSocket(token: String, serverUrl: String) {
|
||||
connectLock.lock()
|
||||
defer { connectLock.unlock() }
|
||||
|
||||
webSocketQueue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.connectLock.lock()
|
||||
defer { self.connectLock.unlock() }
|
||||
|
||||
// Prevent redundant connection attempts
|
||||
if self.currentConnectionState == .connecting || self.currentConnectionState == .connected {
|
||||
print("[WebSocket] Already connecting or connected, ignoring new connect request.")
|
||||
return
|
||||
}
|
||||
|
||||
self.currentConnectionState = .connecting
|
||||
|
||||
// Ensure any existing task is cancelled before starting a new one
|
||||
self.webSocketTask?.cancel(with: .goingAway, reason: nil)
|
||||
@@ -490,13 +492,12 @@ class NetworkService {
|
||||
return
|
||||
}
|
||||
|
||||
print("[WebSocket] Trying connecting to \(url)")
|
||||
self.currentConnectionState = .connecting
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
request.setValue("AtField \(token)", forHTTPHeaderField: "Authorization")
|
||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
|
||||
|
||||
print("[WebSocket] Trying connecting to \(url)")
|
||||
|
||||
self.webSocketTask = self.session.webSocketTask(with: request)
|
||||
self.webSocketTask?.resume()
|
||||
|
||||
|
||||
@@ -19,22 +19,34 @@ class AppState: ObservableObject {
|
||||
let networkService = NetworkService()
|
||||
private var wcService = WatchConnectivityService()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var hasAttemptedConnection = false
|
||||
|
||||
init() {
|
||||
wcService.$token.combineLatest(wcService.$serverUrl)
|
||||
wcService.$token.combineLatest(wcService.$serverUrl, wcService.$isFetched)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] token, serverUrl in
|
||||
self?.token = token
|
||||
self?.serverUrl = serverUrl
|
||||
if let token = token, let serverUrl = serverUrl {
|
||||
self?.isReady = true
|
||||
// Auto-connect WebSocket here
|
||||
self?.networkService.connectWebSocket(token: token, serverUrl: serverUrl)
|
||||
} else {
|
||||
self?.isReady = false
|
||||
// Disconnect WebSocket if token or serverUrl become nil
|
||||
self?.networkService.disconnectWebSocket()
|
||||
} }
|
||||
.sink { [weak self] (token: String?, serverUrl: String?, isFetched: Bool?) in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.token = token
|
||||
self.serverUrl = serverUrl
|
||||
|
||||
if let token = token, let serverUrl = serverUrl, !token.isEmpty, !serverUrl.isEmpty {
|
||||
self.isReady = true
|
||||
// Only connect once when we have valid credentials and tried fetch from phone
|
||||
if !self.hasAttemptedConnection && isFetched == true {
|
||||
self.hasAttemptedConnection = true
|
||||
print("[AppState] Connecting WebSocket to server: \(serverUrl)")
|
||||
self.networkService.connectWebSocket(token: token, serverUrl: serverUrl)
|
||||
}
|
||||
} else {
|
||||
self.isReady = false
|
||||
if self.hasAttemptedConnection {
|
||||
self.hasAttemptedConnection = false
|
||||
// Disconnect WebSocket if token or serverUrl become invalid
|
||||
self.networkService.disconnectWebSocket()
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import Combine
|
||||
class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
|
||||
@Published var token: String?
|
||||
@Published var serverUrl: String?
|
||||
@Published var isFetched: Bool?
|
||||
|
||||
private let session: WCSession
|
||||
private let userDefaults = UserDefaults.standard
|
||||
@@ -30,6 +31,7 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
|
||||
// Load cached data
|
||||
self.token = userDefaults.string(forKey: tokenKey)
|
||||
self.serverUrl = userDefaults.string(forKey: serverUrlKey)
|
||||
self.isFetched = false
|
||||
}
|
||||
|
||||
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||
@@ -58,7 +60,13 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
|
||||
}
|
||||
|
||||
func requestDataFromPhone() {
|
||||
if self.isFetched == true {
|
||||
print("[watchOS] Skipped fetch from phone due to tried.")
|
||||
return
|
||||
}
|
||||
|
||||
guard session.isReachable else {
|
||||
self.isFetched = true
|
||||
print("[watchOS] Phone is not reachable")
|
||||
return
|
||||
}
|
||||
@@ -68,6 +76,7 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
|
||||
guard let self = self else { return }
|
||||
print("[watchOS] Received reply: \(response)")
|
||||
DispatchQueue.main.async {
|
||||
self.isFetched = true
|
||||
if let token = response["token"] as? String {
|
||||
self.token = token
|
||||
self.userDefaults.set(token, forKey: self.tokenKey)
|
||||
|
||||
@@ -49,9 +49,6 @@ struct ExploreView: View {
|
||||
.environmentObject(appState)
|
||||
} else {
|
||||
ProgressView { Text("Connecting to phone...") }
|
||||
.onAppear {
|
||||
appState.requestData()
|
||||
}
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $isComposing) {
|
||||
|
||||
Reference in New Issue
Block a user