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