🐛 Fix some production issue for watchOS Solian

This commit is contained in:
2025-10-31 23:09:08 +08:00
parent 7f971bcee3
commit a2b0cd0b6a
5 changed files with 44 additions and 13 deletions

View File

@@ -182,8 +182,6 @@
/* Begin PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFileSystemSynchronizedRootGroup section */
7310A7D52EB10962002C0FD3 /* WatchRunner Watch App */ = { 7310A7D52EB10962002C0FD3 /* WatchRunner Watch App */ = {
isa = PBXFileSystemSynchronizedRootGroup; isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
);
path = "WatchRunner Watch App"; path = "WatchRunner Watch App";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@@ -671,10 +669,14 @@
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
); );
inputPaths = (
);
name = "[CP] Copy Pods Resources"; name = "[CP] Copy Pods Resources";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
); );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
@@ -732,10 +734,14 @@
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
inputPaths = (
);
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
); );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
@@ -786,10 +792,14 @@
inputFileListPaths = ( inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-input-files.xcfilelist",
); );
inputPaths = (
);
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputFileListPaths = ( outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist", "${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks-${CONFIGURATION}-output-files.xcfilelist",
); );
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WatchRunner Watch App/Pods-WatchRunner Watch App-frameworks.sh\"\n"; 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; GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian;
INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO;
@@ -1146,7 +1156,7 @@
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian;
INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO;
@@ -1195,7 +1205,7 @@
GCC_C_LANGUAGE_STANDARD = gnu17; GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist"; INFOPLIST_FILE = "WatchRunner-Watch-App-Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = WatchRunner; INFOPLIST_KEY_CFBundleDisplayName = Solian;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = dev.solsynth.solian;
INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO;

View File

@@ -15,6 +15,7 @@ class AppState: ObservableObject {
@Published var token: String? = nil @Published var token: String? = nil
@Published var serverUrl: String? = nil @Published var serverUrl: String? = nil
@Published var isReady = false @Published var isReady = false
@Published var errorMessage: String? = nil
let networkService = NetworkService() let networkService = NetworkService()
private var wcService = WatchConnectivityService() private var wcService = WatchConnectivityService()
@@ -22,13 +23,14 @@ class AppState: ObservableObject {
private var hasAttemptedConnection = false private var hasAttemptedConnection = false
init() { init() {
wcService.$token.combineLatest(wcService.$serverUrl, wcService.$isFetched) wcService.$token.combineLatest(wcService.$serverUrl, wcService.$isFetched, wcService.$errorMessage)
.receive(on: DispatchQueue.main) .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 } guard let self = self else { return }
self.token = token self.token = token
self.serverUrl = serverUrl self.serverUrl = serverUrl
self.errorMessage = errorMessage
if let token = token, let serverUrl = serverUrl, !token.isEmpty, !serverUrl.isEmpty { if let token = token, let serverUrl = serverUrl, !token.isEmpty, !serverUrl.isEmpty {
self.isReady = true self.isReady = true

View File

@@ -15,6 +15,7 @@ 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? @Published var isFetched: Bool?
@Published var errorMessage: String?
private let session: WCSession private let session: WCSession
private let userDefaults = UserDefaults.standard private let userDefaults = UserDefaults.standard
@@ -37,6 +38,9 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
if let error = error { if let error = error {
print("[watchOS] WCSession activation failed with error: \(error.localizedDescription)") print("[watchOS] WCSession activation failed with error: \(error.localizedDescription)")
DispatchQueue.main.async {
self.errorMessage = "WCSession activation failed: \(error.localizedDescription)"
}
return return
} }
print("[watchOS] WCSession activated with state: \(activationState.rawValue)") print("[watchOS] WCSession activated with state: \(activationState.rawValue)")
@@ -67,7 +71,11 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
guard session.isReachable else { guard session.isReachable else {
self.isFetched = true 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 return
} }
@@ -88,6 +96,9 @@ class WatchConnectivityService: NSObject, WCSessionDelegate, ObservableObject {
} }
} errorHandler: { error in } errorHandler: { error in
print("[watchOS] sendMessage failed with error: \(error.localizedDescription)") print("[watchOS] sendMessage failed with error: \(error.localizedDescription)")
DispatchQueue.main.async {
self.errorMessage = "Failed to get data from phone: \(error.localizedDescription)"
}
} }
} }
} }

View File

@@ -9,7 +9,7 @@ import SwiftUI
// The main view with the TabView for filtering. // The main view with the TabView for filtering.
struct ExploreView: View { struct ExploreView: View {
@StateObject private var appState = AppState() @EnvironmentObject private var appState: AppState
@State private var isComposing = false @State private var isComposing = false
@State private var selectedTab: String = "Explore" @State private var selectedTab: String = "Explore"
@@ -46,14 +46,22 @@ struct ExploreView: View {
} }
} }
} }
.environmentObject(appState)
} else { } else {
ProgressView { Text("Connecting to phone...") } VStack {
ProgressView { Text("Syncing...") }
Button("Retry") {
appState.requestData()
}
}
} }
} }
.sheet(isPresented: $isComposing) { .sheet(isPresented: $isComposing) {
ComposePostView() ComposePostView()
.environmentObject(appState)
} }
.alert("Error", isPresented: .constant(appState.errorMessage != nil), actions: {
Button("OK") { appState.errorMessage = nil }
}, message: {
Text(appState.errorMessage ?? "")
})
} }
} }

View File

@@ -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 # 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 # 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. # 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: environment:
sdk: ^3.7.2 sdk: ^3.7.2