diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 671dbfe2..5426a8f9 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -182,8 +182,6 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ 7310A7D52EB10962002C0FD3 /* WatchRunner Watch App */ = { isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - ); path = "WatchRunner Watch App"; sourceTree = ""; }; @@ -671,10 +669,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -732,10 +734,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; @@ -786,10 +792,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks.sh\"\n"; @@ -1095,7 +1105,7 @@ GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; + INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; @@ -1146,7 +1156,7 @@ GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; + INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; @@ -1195,7 +1205,7 @@ GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; + INFOPLIST_KEY_CFBundleDisplayName = Solian; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; diff --git a/ios/WatchRunner Watch App/State/AppState.swift b/ios/WatchRunner Watch App/State/AppState.swift index df67e909..a91e7e93 100644 --- a/ios/WatchRunner Watch App/State/AppState.swift +++ b/ios/WatchRunner Watch App/State/AppState.swift @@ -15,6 +15,7 @@ class AppState: ObservableObject { @Published var token: String? = nil @Published var serverUrl: String? = nil @Published var isReady = false + @Published var errorMessage: String? = nil let networkService = NetworkService() private var wcService = WatchConnectivityService() @@ -22,13 +23,14 @@ class AppState: ObservableObject { private var hasAttemptedConnection = false init() { - wcService.$token.combineLatest(wcService.$serverUrl, wcService.$isFetched) + wcService.$token.combineLatest(wcService.$serverUrl, wcService.$isFetched, wcService.$errorMessage) .receive(on: DispatchQueue.main) - .sink { [weak self] (token: String?, serverUrl: String?, isFetched: Bool?) in + .sink { [weak self] (token: String?, serverUrl: String?, isFetched: Bool?, errorMessage: String?) in guard let self = self else { return } self.token = token self.serverUrl = serverUrl + self.errorMessage = errorMessage if let token = token, let serverUrl = serverUrl, !token.isEmpty, !serverUrl.isEmpty { self.isReady = true diff --git a/ios/WatchRunner Watch App/State/WatchConnectivityService.swift b/ios/WatchRunner Watch App/State/WatchConnectivityService.swift index 7db1f9a8..88f18465 100644 --- a/ios/WatchRunner Watch App/State/WatchConnectivityService.swift +++ b/ios/WatchRunner Watch App/State/WatchConnectivityService.swift @@ -15,6 +15,7 @@ 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 @@ -37,6 +38,9 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject { 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)") @@ -67,7 +71,11 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject { guard session.isReachable else { self.isFetched = true - print("[watchOS] Phone is not reachable") + let errorMsg = "Phone is not reachable" + print("[watchOS] \(errorMsg)") + DispatchQueue.main.async { + self.errorMessage = errorMsg + } return } @@ -88,6 +96,9 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject { } } errorHandler: { error in print("[watchOS] sendMessage failed with error: \(error.localizedDescription)") + DispatchQueue.main.async { + self.errorMessage = "Failed to get data from phone: \(error.localizedDescription)" + } } } } diff --git a/ios/WatchRunner Watch App/Views/ExploreView.swift b/ios/WatchRunner Watch App/Views/ExploreView.swift index 692905c0..f741174d 100644 --- a/ios/WatchRunner Watch App/Views/ExploreView.swift +++ b/ios/WatchRunner Watch App/Views/ExploreView.swift @@ -9,7 +9,7 @@ import SwiftUI // The main view with the TabView for filtering. struct ExploreView: View { - @StateObject private var appState = AppState() + @EnvironmentObject private var appState: AppState @State private var isComposing = false @State private var selectedTab: String = "Explore" @@ -46,14 +46,22 @@ struct ExploreView: View { } } } - .environmentObject(appState) } else { - ProgressView { Text("Connecting to phone...") } + VStack { + ProgressView { Text("Syncing...") } + Button("Retry") { + appState.requestData() + } + } } } .sheet(isPresented: $isComposing) { ComposePostView() - .environmentObject(appState) } + .alert("Error", isPresented: .constant(appState.errorMessage != nil), actions: { + Button("OK") { appState.errorMessage = nil } + }, message: { + Text(appState.errorMessage ?? "") + }) } } diff --git a/pubspec.yaml b/pubspec.yaml index 3bed8d74..77ce22f6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 3.3.0+139 +version: 3.3.0+140 environment: sdk: ^3.7.2