mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
opt.: watch sync mechanism (#817)
* opt.: watch sync mechanism Fixes #816 * opt.
This commit is contained in:
@@ -14,11 +14,18 @@ class PhoneConnMgr: NSObject, WCSessionDelegate, ObservableObject {
|
||||
set {
|
||||
Store.setCtx(newValue)
|
||||
updateUrls(newValue)
|
||||
|
||||
// Notify the view to update, but the [urls] are already published
|
||||
// so the view will automatically update when [urls] changes.
|
||||
// DispatchQueue.main.async {
|
||||
// self.objectWillChange.send()
|
||||
// }
|
||||
}
|
||||
get {
|
||||
return _ctx
|
||||
}
|
||||
}
|
||||
var userInfo: [String: Any] = [:]
|
||||
@Published var urls: [String] = []
|
||||
|
||||
override init() {
|
||||
@@ -30,23 +37,84 @@ class PhoneConnMgr: NSObject, WCSessionDelegate, ObservableObject {
|
||||
session?.delegate = self
|
||||
session?.activate()
|
||||
|
||||
ctx = Store.getCtx()
|
||||
_ctx = Store.getCtx()
|
||||
updateUrls(_ctx)
|
||||
}
|
||||
|
||||
func updateUrls(_ val: [String: Any]) {
|
||||
if let urls = val["urls"] as? [String] {
|
||||
self.urls = urls.filter { !$0.isEmpty }
|
||||
DispatchQueue.main.async {
|
||||
self.urls = urls.filter { !$0.isEmpty }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||
|
||||
func session(
|
||||
_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState,
|
||||
error: Error?
|
||||
) {
|
||||
// Request latest data when the session is activated
|
||||
if activationState == .activated {
|
||||
requestLatestData()
|
||||
}
|
||||
}
|
||||
|
||||
// implement session:didReceiveApplicationContext:
|
||||
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
|
||||
ctx = applicationContext
|
||||
// Receive realtime msgs
|
||||
func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
|
||||
DispatchQueue.main.async {
|
||||
self.ctx = message
|
||||
}
|
||||
}
|
||||
|
||||
// Receive UserInfo
|
||||
func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any]) {
|
||||
DispatchQueue.main.async {
|
||||
self.ctx = userInfo
|
||||
}
|
||||
}
|
||||
|
||||
// Receive Application Context
|
||||
func session(
|
||||
_ session: WCSession, didReceiveApplicationContext applicationContext: [String: Any]
|
||||
) {
|
||||
DispatchQueue.main.async {
|
||||
self.ctx = applicationContext
|
||||
}
|
||||
}
|
||||
|
||||
private func requestLatestData(timeout: TimeInterval = 5.0, maxRetries: Int = 1) {
|
||||
guard let session = session, session.isReachable else { return }
|
||||
|
||||
var didReceiveResponse = false
|
||||
var retries = 0
|
||||
|
||||
func sendRequest() {
|
||||
session.sendMessage(["action": "requestData"]) { response in
|
||||
didReceiveResponse = true
|
||||
DispatchQueue.main.async {
|
||||
self.ctx = response
|
||||
}
|
||||
} errorHandler: { error in
|
||||
print("Request data failed: \(error)")
|
||||
// Optionally, handle error UI here
|
||||
}
|
||||
|
||||
// Timeout handling
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + timeout) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if !didReceiveResponse {
|
||||
if retries < maxRetries {
|
||||
retries += 1
|
||||
print("No response, retrying requestLatestData (\(retries))...")
|
||||
sendRequest()
|
||||
} else {
|
||||
print("Request data timed out after \(retries + 1) attempts.")
|
||||
// Optionally, update UI to indicate timeout
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendRequest()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -114,7 +114,20 @@ class _IosSettingsPageState extends State<IosSettingsPage> {
|
||||
|
||||
final (_, err) = await context.showLoadingDialog(
|
||||
fn: () async {
|
||||
await wc.updateApplicationContext({'urls': result});
|
||||
final data = {'urls': result};
|
||||
|
||||
// Try realtime update (app must be running foreground).
|
||||
try {
|
||||
if (await wc.isReachable) {
|
||||
await wc.sendMessage(data);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
Loggers.app.warning('Failed to send message to watch', e);
|
||||
}
|
||||
|
||||
// fallback
|
||||
await wc.updateApplicationContext(data);
|
||||
},
|
||||
);
|
||||
if (err == null) {
|
||||
|
||||
Reference in New Issue
Block a user