114 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Swift
		
	
	
	
	
	
import WatchConnectivity
 | 
						|
import Combine
 | 
						|
import Foundation
 | 
						|
 | 
						|
class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
 | 
						|
    @Published var token: String?
 | 
						|
    @Published var serverUrl: String?
 | 
						|
    @Published var isFetched: Bool?
 | 
						|
    @Published var errorMessage: String?
 | 
						|
 | 
						|
    private let session: WCSession
 | 
						|
    private let userDefaults = UserDefaults.standard
 | 
						|
    private let tokenKey = "token"
 | 
						|
    private let serverUrlKey = "serverUrl"
 | 
						|
 | 
						|
    override init() {
 | 
						|
        self.session = .default
 | 
						|
        super.init()
 | 
						|
        print("[watchOS] Activating WCSession")
 | 
						|
        self.session.delegate = self
 | 
						|
        self.session.activate()
 | 
						|
        
 | 
						|
        // 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?) {
 | 
						|
        if let error = error {
 | 
						|
            print("[watchOS] WCSession activation failed with error: \(error.localizedDescription)")
 | 
						|
            DispatchQueue.main.async {
 | 
						|
                self.errorMessage = "WCSession activation failed: \(error.localizedDescription)"
 | 
						|
            }
 | 
						|
            return
 | 
						|
        }
 | 
						|
        print("[watchOS] WCSession activated with state: \(activationState.rawValue)")
 | 
						|
        if activationState == .activated {
 | 
						|
            requestDataFromPhone()
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
 | 
						|
        print("[watchOS] Received application context: \(applicationContext)")
 | 
						|
        DispatchQueue.main.async {
 | 
						|
            if let token = applicationContext["token"] as? String {
 | 
						|
                self.token = token
 | 
						|
                self.userDefaults.set(token, forKey: self.tokenKey)
 | 
						|
            }
 | 
						|
            if let serverUrl = applicationContext["serverUrl"] as? String {
 | 
						|
                self.serverUrl = serverUrl
 | 
						|
                self.userDefaults.set(serverUrl, forKey: self.serverUrlKey)
 | 
						|
            }
 | 
						|
            self.isFetched = true
 | 
						|
            self.errorMessage = nil
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
 | 
						|
        print("[watchOS] Received message: \(message)")
 | 
						|
        DispatchQueue.main.async {
 | 
						|
            if let token = message["token"] as? String {
 | 
						|
                self.token = token
 | 
						|
                self.userDefaults.set(token, forKey: self.tokenKey)
 | 
						|
            }
 | 
						|
            if let serverUrl = message["serverUrl"] as? String {
 | 
						|
                self.serverUrl = serverUrl
 | 
						|
                self.userDefaults.set(serverUrl, forKey: self.serverUrlKey)
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    func requestDataFromPhone() {
 | 
						|
    // Check if we already have valid data to avoid unnecessary requests
 | 
						|
    if let token = self.token, let serverUrl = self.serverUrl, !token.isEmpty, !serverUrl.isEmpty {
 | 
						|
        print("[watchOS] Skipped fetch - already have valid data")
 | 
						|
        self.isFetched = true
 | 
						|
        return
 | 
						|
    }
 | 
						|
    
 | 
						|
    guard session.activationState == .activated else {
 | 
						|
        print("[watchOS] Session not activated yet, state: \(session.activationState.rawValue)")
 | 
						|
        DispatchQueue.main.async {
 | 
						|
            self.errorMessage = "Session not ready yet"
 | 
						|
        }
 | 
						|
        return
 | 
						|
    }
 | 
						|
    
 | 
						|
    print("[watchOS] Requesting data from phone")
 | 
						|
    session.sendMessage(["request": "data"]) { [weak self] response in
 | 
						|
        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)
 | 
						|
            }
 | 
						|
            if let serverUrl = response["serverUrl"] as? String {
 | 
						|
                self.serverUrl = serverUrl
 | 
						|
                self.userDefaults.set(serverUrl, forKey: self.serverUrlKey)
 | 
						|
            }
 | 
						|
            self.errorMessage = nil // Clear any previous errors
 | 
						|
        }
 | 
						|
    } errorHandler: { error in
 | 
						|
        print("[watchOS] sendMessage failed with error: \(error.localizedDescription)")
 | 
						|
        DispatchQueue.main.async {
 | 
						|
            self.errorMessage = "Failed to get data from phone: \(error.localizedDescription)"
 | 
						|
            // Don't set isFetched = true on error - allow retry
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
}
 |