Showing
11 changed files
with
258 additions
and
224 deletions
| @@ -27,24 +27,24 @@ final class HealthDataReader { | @@ -27,24 +27,24 @@ final class HealthDataReader { | ||
| 27 | startDate: startDate, | 27 | startDate: startDate, |
| 28 | endDate: endDate | 28 | endDate: endDate |
| 29 | ) | 29 | ) |
| 30 | - async let activeEnergy = fetchQuantitySamples( | 30 | + async let activeEnergy = fetchDailyCumulativeSamples( |
| 31 | identifier: .activeEnergyBurned, | 31 | identifier: .activeEnergyBurned, |
| 32 | dataType: .activeEnergy, | 32 | dataType: .activeEnergy, |
| 33 | unit: .kilocalorie(), | 33 | unit: .kilocalorie(), |
| 34 | startDate: startDate, | 34 | startDate: startDate, |
| 35 | endDate: endDate | 35 | endDate: endDate |
| 36 | ) | 36 | ) |
| 37 | - async let exercise = fetchQuantitySamples( | 37 | + async let exercise = fetchDailyCumulativeSamples( |
| 38 | identifier: .appleExerciseTime, | 38 | identifier: .appleExerciseTime, |
| 39 | dataType: .exercise, | 39 | dataType: .exercise, |
| 40 | - unit: .minute(), | 40 | + unit: .second(), |
| 41 | startDate: startDate, | 41 | startDate: startDate, |
| 42 | endDate: endDate | 42 | endDate: endDate |
| 43 | ) | 43 | ) |
| 44 | - async let stand = fetchQuantitySamples( | 44 | + async let stand = fetchDailyCumulativeSamples( |
| 45 | identifier: .appleStandTime, | 45 | identifier: .appleStandTime, |
| 46 | dataType: .stand, | 46 | dataType: .stand, |
| 47 | - unit: .minute(), | 47 | + unit: .second(), |
| 48 | startDate: startDate, | 48 | startDate: startDate, |
| 49 | endDate: endDate | 49 | endDate: endDate |
| 50 | ) | 50 | ) |
| @@ -203,37 +203,40 @@ final class HealthDataReader { | @@ -203,37 +203,40 @@ final class HealthDataReader { | ||
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | func fetchActiveEnergyData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { | 205 | func fetchActiveEnergyData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { |
| 206 | - try await fetchQuantitySamples( | ||
| 207 | - identifier: .activeEnergyBurned, | ||
| 208 | - dataType: .activeEnergy, | ||
| 209 | - unit: .kilocalorie(), | ||
| 210 | - startDate: startDate, | ||
| 211 | - endDate: endDate | ||
| 212 | - ) | 206 | + try await fetchDailyCumulativeSamples(identifier: .activeEnergyBurned, dataType: .activeEnergy, unit: .kilocalorie(), startDate: startDate, endDate: endDate) |
| 207 | +// try await fetchQuantitySamples( | ||
| 208 | +// identifier: .activeEnergyBurned, | ||
| 209 | +// dataType: .activeEnergy, | ||
| 210 | +// unit: .kilocalorie(), | ||
| 211 | +// startDate: startDate, | ||
| 212 | +// endDate: endDate | ||
| 213 | +// ) | ||
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | func fetchExerciseData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { | 216 | func fetchExerciseData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { |
| 216 | - try await fetchQuantitySamples( | ||
| 217 | - identifier: .appleExerciseTime, | ||
| 218 | - dataType: .exercise, | ||
| 219 | - unit: .minute(), | ||
| 220 | - startDate: startDate, | ||
| 221 | - endDate: endDate | ||
| 222 | - ) | 217 | + try await fetchDailyCumulativeSamples(identifier: .appleExerciseTime, dataType: .exercise, unit: .second(), startDate: startDate, endDate: endDate) |
| 218 | +// try await fetchQuantitySamples( | ||
| 219 | +// identifier: .appleExerciseTime, | ||
| 220 | +// dataType: .exercise, | ||
| 221 | +// unit: .minute(), | ||
| 222 | +// startDate: startDate, | ||
| 223 | +// endDate: endDate | ||
| 224 | +// ) | ||
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | func fetchStandData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { | 227 | func fetchStandData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { |
| 226 | - try await fetchQuantitySamples( | ||
| 227 | - identifier: .appleStandTime, | ||
| 228 | - dataType: .stand, | ||
| 229 | - unit: .minute(), | ||
| 230 | - startDate: startDate, | ||
| 231 | - endDate: endDate | ||
| 232 | - ) | 228 | + try await fetchDailyCumulativeSamples(identifier: .appleStandTime, dataType: .stand, unit: .second(), startDate: startDate, endDate: endDate) |
| 229 | +// try await fetchQuantitySamples( | ||
| 230 | +// identifier: .appleStandTime, | ||
| 231 | +// dataType: .stand, | ||
| 232 | +// unit: .minute(), | ||
| 233 | +// startDate: startDate, | ||
| 234 | +// endDate: endDate | ||
| 235 | +// ) | ||
| 233 | } | 236 | } |
| 234 | 237 | ||
| 235 | func fetchStepCountData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { | 238 | func fetchStepCountData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { |
| 236 | - try await fetchDailyCumulativeSamples( | 239 | + try await fetchDailyCumulativeSamples( |
| 237 | identifier: .stepCount, | 240 | identifier: .stepCount, |
| 238 | dataType: .steps, | 241 | dataType: .steps, |
| 239 | unit: .count(), | 242 | unit: .count(), |
| @@ -336,6 +339,7 @@ final class HealthDataReader { | @@ -336,6 +339,7 @@ final class HealthDataReader { | ||
| 336 | guard let type = NativeHealthTypeCatalog.quantity(identifier) else { | 339 | guard let type = NativeHealthTypeCatalog.quantity(identifier) else { |
| 337 | throw NativeHealthKitError.invalidType(identifier.rawValue) | 340 | throw NativeHealthKitError.invalidType(identifier.rawValue) |
| 338 | } | 341 | } |
| 342 | + | ||
| 339 | let predicate = HKQuery.predicateForSamples( | 343 | let predicate = HKQuery.predicateForSamples( |
| 340 | withStart: startDate, | 344 | withStart: startDate, |
| 341 | end: endDate, | 345 | end: endDate, |
| @@ -143,20 +143,7 @@ final class HealthKitService { | @@ -143,20 +143,7 @@ final class HealthKitService { | ||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | func refreshSharedWatchValues() async { | 145 | func refreshSharedWatchValues() async { |
| 146 | - do { | ||
| 147 | - if let hrv = try await reader.fetchLatestHRV() { | ||
| 148 | - AppGroupConstants.defaults?.set(hrv, forKey: AppGroupConstants.Key.latestHRV) | ||
| 149 | - } | ||
| 150 | - } catch { | ||
| 151 | - // Keep the previous widget value when a single read fails. | ||
| 152 | - } | ||
| 153 | - | ||
| 154 | - do { | ||
| 155 | - let steps = try await reader.fetchTodayStepCount() | ||
| 156 | - AppGroupConstants.defaults?.set(steps, forKey: AppGroupConstants.Key.latestStepCount) | ||
| 157 | - } catch { | ||
| 158 | - // Keep the previous widget value when a single read fails. | ||
| 159 | - } | 146 | + _ = WatchConnectivityService.shared.sendCommandMessage(AppGroupMessageKey.statusPulseRefresh) |
| 160 | } | 147 | } |
| 161 | 148 | ||
| 162 | func fetchHrvData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { | 149 | func fetchHrvData(startDate: Date, endDate: Date) async throws -> [NativeHealthDataPoint] { |
| @@ -58,7 +58,7 @@ final class NativeHealthDataUploader { | @@ -58,7 +58,7 @@ final class NativeHealthDataUploader { | ||
| 58 | var sleepUploadSuccess = true | 58 | var sleepUploadSuccess = true |
| 59 | var errorMessages: [String] = [] | 59 | var errorMessages: [String] = [] |
| 60 | 60 | ||
| 61 | - debugLog("uploadAll started, userId=\(AppShared.shared.userId ?? "<nil>")") | 61 | + debugLog("uploadAll started ") |
| 62 | do { | 62 | do { |
| 63 | let uploadTimeList = try await processLastUploadTime() | 63 | let uploadTimeList = try await processLastUploadTime() |
| 64 | 64 | ||
| @@ -512,10 +512,7 @@ struct NativeHealthUploadTimeRecorder { | @@ -512,10 +512,7 @@ struct NativeHealthUploadTimeRecorder { | ||
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | private static func cacheKeyForCurrentUser() -> String { | 514 | private static func cacheKeyForCurrentUser() -> String { |
| 515 | - let userId = AppShared.shared.userId | ||
| 516 | - ?? AppShared.shared.userSummary?.meUserInfo?.id.map(String.init) | ||
| 517 | - ?? AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.userId) | ||
| 518 | - ?? "" | 515 | + let userId = "\(AppShared.shared.userId ?? 0)" |
| 519 | return cacheKey + userId | 516 | return cacheKey + userId |
| 520 | } | 517 | } |
| 521 | } | 518 | } |
| @@ -54,7 +54,7 @@ final class PlatformHostApiImpl: PlatformHostApi { | @@ -54,7 +54,7 @@ final class PlatformHostApiImpl: PlatformHostApi { | ||
| 54 | return false | 54 | return false |
| 55 | #endif | 55 | #endif |
| 56 | } | 56 | } |
| 57 | - | 57 | + |
| 58 | func nativeHandleUrl(urlString: String) throws -> Bool { | 58 | func nativeHandleUrl(urlString: String) throws -> Bool { |
| 59 | if let url = URL(string: urlString){ | 59 | if let url = URL(string: urlString){ |
| 60 | UIApplication.shared.open(url) | 60 | UIApplication.shared.open(url) |
| @@ -62,7 +62,7 @@ final class PlatformHostApiImpl: PlatformHostApi { | @@ -62,7 +62,7 @@ final class PlatformHostApiImpl: PlatformHostApi { | ||
| 62 | } | 62 | } |
| 63 | return false | 63 | return false |
| 64 | } | 64 | } |
| 65 | - | 65 | + |
| 66 | func requestUnhandedUrl() throws -> String? { | 66 | func requestUnhandedUrl() throws -> String? { |
| 67 | let unhandedUrl = AppShared.shared.unhandedUrl | 67 | let unhandedUrl = AppShared.shared.unhandedUrl |
| 68 | AppShared.shared.unhandedUrl = nil | 68 | AppShared.shared.unhandedUrl = nil |
| @@ -124,26 +124,23 @@ final class PlatformHostApiImpl: PlatformHostApi { | @@ -124,26 +124,23 @@ final class PlatformHostApiImpl: PlatformHostApi { | ||
| 124 | 124 | ||
| 125 | // 登录 | 125 | // 登录 |
| 126 | func updateLoginInfo(jsonString: String, baseUrl: String) throws { | 126 | func updateLoginInfo(jsonString: String, baseUrl: String) throws { |
| 127 | - AppShared.shared.baseUrl = baseUrl | ||
| 128 | if let data = jsonString.data(using: .utf8){ | 127 | if let data = jsonString.data(using: .utf8){ |
| 129 | do{ | 128 | do{ |
| 130 | let model = try JSONDecoder().decode(FlutterUserSummary.self, from: data) | 129 | let model = try JSONDecoder().decode(FlutterUserSummary.self, from: data) |
| 131 | - AppShared.shared.userSummary = model | ||
| 132 | - | ||
| 133 | - AppGroupConstants.defaults?.set(baseUrl, forKey: AppGroupConstants.Key.baseUrl) | ||
| 134 | - if let userId = model.meUserInfo?.id.map(String.init), !userId.isEmpty { | ||
| 135 | - AppGroupConstants.defaults?.set(userId, forKey: AppGroupConstants.Key.userId) | ||
| 136 | - AppShared.shared.userId = userId | ||
| 137 | - } | ||
| 138 | if let token = model.accessToken{ | 130 | if let token = model.accessToken{ |
| 139 | - AppGroupConstants.defaults?.set(token, forKey: AppGroupConstants.Key.token) | ||
| 140 | // 刷新用户信息 | 131 | // 刷新用户信息 |
| 141 | - _ = WatchConnectivityService.shared.sendTextMessage(AppGroupMessageKey.login) | 132 | + let watchUser = UserInfoModel(userId: model.meUserInfo?.id, token: token, baseUrl: baseUrl) |
| 133 | + do{ | ||
| 134 | + let data = try JSONEncoder().encode(watchUser) | ||
| 135 | + AppGroupConstants.defaults?.set(data, forKey: AppGroupConstants.Key.myUserInfo) | ||
| 136 | + AppShared.shared.login(userInfo: watchUser) | ||
| 137 | + _ = WatchConnectivityService.shared.sendLoginInfoMessage(userInfo: watchUser) | ||
| 138 | + | ||
| 139 | + }catch{} | ||
| 142 | 140 | ||
| 143 | Task{ | 141 | Task{ |
| 144 | await AppShared.shared.reportDeviceInfo() | 142 | await AppShared.shared.reportDeviceInfo() |
| 145 | } | 143 | } |
| 146 | - AppShared.shared.token = token | ||
| 147 | } | 144 | } |
| 148 | }catch{ | 145 | }catch{ |
| 149 | DebugLogger.log(desc: error.localizedDescription) | 146 | DebugLogger.log(desc: error.localizedDescription) |
| @@ -151,68 +148,24 @@ final class PlatformHostApiImpl: PlatformHostApi { | @@ -151,68 +148,24 @@ final class PlatformHostApiImpl: PlatformHostApi { | ||
| 151 | } | 148 | } |
| 152 | } | 149 | } |
| 153 | 150 | ||
| 154 | - private static func extractUserId(from data: Data) -> String? { | ||
| 155 | - guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else { | ||
| 156 | - return nil | ||
| 157 | - } | ||
| 158 | - | ||
| 159 | - if let userId = stringify(json["userId"]) ?? stringify(json["user_id"]) { | ||
| 160 | - return userId | ||
| 161 | - } | ||
| 162 | - | ||
| 163 | - if let meUserInfo = json["me_user_info"] as? [String: Any] { | ||
| 164 | - return stringify(meUserInfo["id"]) ?? stringify(meUserInfo["userId"]) ?? stringify(meUserInfo["user_id"]) | ||
| 165 | - } | ||
| 166 | - | ||
| 167 | - return nil | ||
| 168 | - } | ||
| 169 | - | ||
| 170 | - private static func stringify(_ value: Any?) -> String? { | ||
| 171 | - switch value { | ||
| 172 | - case let value as String: | ||
| 173 | - return value | ||
| 174 | - case let value as Int: | ||
| 175 | - return String(value) | ||
| 176 | - case let value as Int64: | ||
| 177 | - return String(value) | ||
| 178 | - case let value as NSNumber: | ||
| 179 | - return value.stringValue | ||
| 180 | - default: | ||
| 181 | - return nil | ||
| 182 | - } | ||
| 183 | - } | ||
| 184 | - | ||
| 185 | // 退出登录 | 151 | // 退出登录 |
| 186 | func logout() throws { | 152 | func logout() throws { |
| 187 | // 清除所有数据 | 153 | // 清除所有数据 |
| 188 | - AppGroupConstants.defaults?.dictionaryRepresentation().keys.forEach({ | ||
| 189 | - AppGroupConstants.defaults?.removeObject(forKey: $0) | ||
| 190 | - }) | ||
| 191 | AppShared.shared.logout() | 154 | AppShared.shared.logout() |
| 192 | - _ = WatchConnectivityService.shared.sendTextMessage(AppGroupMessageKey.logout) | 155 | + _ = WatchConnectivityService.shared.sendLoginInfoMessage(userInfo: nil) |
| 193 | } | 156 | } |
| 194 | // 刷新会员 | 157 | // 刷新会员 |
| 195 | func refreshVip() throws { | 158 | func refreshVip() throws { |
| 196 | - _ = WatchConnectivityService.shared.sendTextMessage(AppGroupMessageKey.reloadVip) | 159 | + _ = WatchConnectivityService.shared.sendCommandMessage(AppGroupMessageKey.reloadVip) |
| 197 | } | 160 | } |
| 198 | // 刷新watch app 和表盘 | 161 | // 刷新watch app 和表盘 |
| 199 | func refreshWatchAppAndWidgets() throws { | 162 | func refreshWatchAppAndWidgets() throws { |
| 200 | - _ = WatchConnectivityService.shared.sendTextMessage(AppGroupMessageKey.reloadAll) | 163 | + _ = WatchConnectivityService.shared.sendCommandMessage(AppGroupMessageKey.reloadAll) |
| 201 | } | 164 | } |
| 202 | // 设置/移除 好友显示到表盘 | 165 | // 设置/移除 好友显示到表盘 |
| 203 | func updateWatchOtherUserInfo(otherInfo: WatchAppOtherInfo?) throws { | 166 | func updateWatchOtherUserInfo(otherInfo: WatchAppOtherInfo?) throws { |
| 204 | - defer{ | ||
| 205 | - try? refreshWatchAppAndWidgets() | ||
| 206 | - } | ||
| 207 | - | ||
| 208 | - guard let otherInfo else{ | ||
| 209 | - AppGroupConstants.defaults?.removeObject(forKey: AppGroupConstants.Key.showOtherUserInfo) | ||
| 210 | - return | ||
| 211 | - } | ||
| 212 | - | ||
| 213 | do{ | 167 | do{ |
| 214 | - let data = try JSONSerialization.data(withJSONObject: otherInfo.toParams()) | ||
| 215 | - AppGroupConstants.defaults?.set(data, forKey: AppGroupConstants.Key.showOtherUserInfo) | 168 | + try refreshWatchAppAndWidgets() |
| 216 | }catch{ | 169 | }catch{ |
| 217 | 170 | ||
| 218 | } | 171 | } |
| @@ -37,7 +37,7 @@ final class WearEngineHostApiImpl: WearEngineHostApi { | @@ -37,7 +37,7 @@ final class WearEngineHostApiImpl: WearEngineHostApi { | ||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | func sendWatchSyncPayload(jsonPayload: String) throws -> Bool { | 39 | func sendWatchSyncPayload(jsonPayload: String) throws -> Bool { |
| 40 | - WatchConnectivityService.shared.sendWatchThemeChangedMessage() | 40 | + WatchConnectivityService.shared.sendWatchThemeChangedMessage(json: jsonPayload) |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | func removeBackground(originImagePath: String, completion: @escaping (Result<String?, any Error>) -> Void) { | 43 | func removeBackground(originImagePath: String, completion: @escaping (Result<String?, any Error>) -> Void) { |
| @@ -6,48 +6,74 @@ enum AppGroupConstants { | @@ -6,48 +6,74 @@ enum AppGroupConstants { | ||
| 6 | static let identifier = "group.com.luiz.doublefeel.watchkitapp" | 6 | static let identifier = "group.com.luiz.doublefeel.watchkitapp" |
| 7 | 7 | ||
| 8 | enum Key { | 8 | enum Key { |
| 9 | - static let deviceInfo = "deviceInfo" | ||
| 10 | - static let appDeviceToken = "appDeviceToken" | ||
| 11 | - static let watchDeviceToken = "watchDeviceToken" | 9 | + static let deviceInfo = "deviceInfo" |
| 10 | + static let appDeviceToken = "appDeviceToken" | ||
| 11 | + static let watchDeviceToken = "watchDeviceToken" | ||
| 12 | 12 | ||
| 13 | static let latestHealthData = "latestHealthData" | 13 | static let latestHealthData = "latestHealthData" |
| 14 | static let acitivyTarget = "acitivyTarget" | 14 | static let acitivyTarget = "acitivyTarget" |
| 15 | - static let latestHRV = "latestHRV" | ||
| 16 | - static let latestHRVBaseline = "latestHRVBaseline" | ||
| 17 | - static let latestStepCount = "latestStepCount" | ||
| 18 | static let myWatchTheme = "myWatchTheme" | 15 | static let myWatchTheme = "myWatchTheme" |
| 19 | static let otherWatchTheme = "otherWatchTheme" | 16 | static let otherWatchTheme = "otherWatchTheme" |
| 20 | 17 | ||
| 21 | static let myTodayStandTime = "myTodayStandTime" | 18 | static let myTodayStandTime = "myTodayStandTime" |
| 22 | - static let myTodayExerciseTime = "myTodayExerciseTime" | ||
| 23 | - static let myTodayActiveEnergy = "myTodayActiveEnergy" | ||
| 24 | - static let myTodayStepCount = "myTodayStepCount" | ||
| 25 | - static let myLatestHeartRate = "myLatestHeartRate" | 19 | + static let myTodayExerciseTime = "myTodayExerciseTime" |
| 20 | + static let myTodayActiveEnergy = "myTodayActiveEnergy" | ||
| 21 | + static let myTodayStepCount = "myTodayStepCount" | ||
| 22 | + static let myLatestHeartRate = "myLatestHeartRate" | ||
| 26 | 23 | ||
| 27 | - static let myUserCharacter = "myUserCharacter" | ||
| 28 | static let myUserInfo = "myUserInfo" | 24 | static let myUserInfo = "myUserInfo" |
| 29 | - | ||
| 30 | - static let baseUrl = "baseURL" | ||
| 31 | - static let userId = "userId" | ||
| 32 | - static let token = "accessToken" | 25 | + /// flutter登录信息 |
| 26 | + static let userSummary = "flutterUserSummary" | ||
| 27 | + /// 显示好友信息 | ||
| 33 | static let showOtherUserInfo = "showOtherUserInfo" | 28 | static let showOtherUserInfo = "showOtherUserInfo" |
| 34 | - static let vipInfo = "vipInfo" | ||
| 35 | - static let showRealtimeHRV = "showRealtimeHRV" | 29 | + /// 会员信息 |
| 30 | + static let vipInfo = "vipInfo" | ||
| 31 | + static let showRealtimeHRV = "showRealtimeHRV" | ||
| 36 | } | 32 | } |
| 37 | 33 | ||
| 38 | static var defaults: UserDefaults? { | 34 | static var defaults: UserDefaults? { |
| 39 | UserDefaults(suiteName: identifier) | 35 | UserDefaults(suiteName: identifier) |
| 40 | } | 36 | } |
| 37 | + static func clearAllData(){ | ||
| 38 | + defaults?.removePersistentDomain(forName: identifier) | ||
| 39 | + defaults?.synchronize() | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + static func clearUserSessionData() { | ||
| 43 | + [ | ||
| 44 | + Key.latestHealthData, | ||
| 45 | + Key.acitivyTarget, | ||
| 46 | + Key.myWatchTheme, | ||
| 47 | + Key.otherWatchTheme, | ||
| 48 | + Key.myTodayStandTime, | ||
| 49 | + Key.myTodayExerciseTime, | ||
| 50 | + Key.myTodayActiveEnergy, | ||
| 51 | + Key.myTodayStepCount, | ||
| 52 | + Key.myLatestHeartRate, | ||
| 53 | + Key.myUserInfo, | ||
| 54 | + Key.userSummary, | ||
| 55 | + Key.showOtherUserInfo, | ||
| 56 | + Key.vipInfo, | ||
| 57 | + Key.showRealtimeHRV | ||
| 58 | + ].forEach { key in | ||
| 59 | + defaults?.removeObject(forKey: key) | ||
| 60 | + } | ||
| 61 | + defaults?.synchronize() | ||
| 62 | + } | ||
| 41 | } | 63 | } |
| 42 | 64 | ||
| 43 | -struct AppGroupMessageKey { | ||
| 44 | - static let login = "login" | ||
| 45 | - static let logout = "logout" | ||
| 46 | 65 | ||
| 47 | - static let reloadAll = "reloadAll" | ||
| 48 | - static let reloadVip = "reloadVip" | ||
| 49 | - static let reloadTheme = "reloadTheme" | ||
| 50 | 66 | ||
| 51 | - static let statusPulseRefresh = "statusPulseRefresh" | ||
| 52 | - static let watchDeviceToken = "watchDeviceToken" | 67 | +struct AppGroupMessageKey{ |
| 68 | + static let login = "login" | ||
| 69 | + static let logout = "logout" | ||
| 70 | + static let requestLoginState = "requestLoginState" | ||
| 71 | + | ||
| 72 | + static let reloadAll = "reloadAll" | ||
| 73 | + static let reloadVip = "reloadVip" | ||
| 74 | + static let reloadTheme = "reloadTheme" | ||
| 75 | + | ||
| 76 | + // 手表通知app刷新连接状态 | ||
| 77 | + static let statusPulseRefresh = "statusPulseRefresh" | ||
| 78 | + static let watchDeviceToken = "watchDeviceToken" | ||
| 53 | } | 79 | } |
| @@ -11,43 +11,60 @@ let kAppId = "6747254434" | @@ -11,43 +11,60 @@ let kAppId = "6747254434" | ||
| 11 | 11 | ||
| 12 | class AppShared{ | 12 | class AppShared{ |
| 13 | static let shared = AppShared() | 13 | static let shared = AppShared() |
| 14 | - | 14 | + |
| 15 | var isLogin: Bool{ | 15 | var isLogin: Bool{ |
| 16 | - baseUrl.hasPrefix("http") && (userSummary?.accessToken?.count ?? 0 > 0) | 16 | + baseUrl.hasPrefix("http") && (token?.count ?? 0 > 0) |
| 17 | } | 17 | } |
| 18 | - | 18 | + |
| 19 | private(set) var agent = UserAgent() | 19 | private(set) var agent = UserAgent() |
| 20 | private(set) var payment = ApplePayment() | 20 | private(set) var payment = ApplePayment() |
| 21 | - | ||
| 22 | - var baseUrl: String = "https://api.doublefeel.cn" | ||
| 23 | - var token: String? | ||
| 24 | - var userId: String? | ||
| 25 | - var userSummary: FlutterUserSummary? | ||
| 26 | - | 21 | + |
| 22 | + var baseUrl: String{ | ||
| 23 | + myUserInfo?.baseUrl ?? "https://api.doublefeel.cn" | ||
| 24 | + } | ||
| 25 | + var token: String?{ | ||
| 26 | + myUserInfo?.token | ||
| 27 | + } | ||
| 28 | + var userId: Int?{ | ||
| 29 | + myUserInfo?.userId | ||
| 30 | + } | ||
| 31 | + private(set) var myUserInfo: UserInfoModel?{ | ||
| 32 | + didSet{ | ||
| 33 | + WatchConnectivityService.shared.transferLoginInfo(userInfo: myUserInfo) | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + | ||
| 27 | /// 冷启动待处理的urlstring | 37 | /// 冷启动待处理的urlstring |
| 28 | var unhandedUrl: String? | 38 | var unhandedUrl: String? |
| 29 | - | 39 | + |
| 30 | private init(){ | 40 | private init(){ |
| 31 | - login() | 41 | + login(userInfo: nil) |
| 32 | } | 42 | } |
| 33 | 43 | ||
| 34 | - func login(){ | ||
| 35 | - token = AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.token) | ||
| 36 | - userId = AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.userId) | ||
| 37 | - if let url = AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.baseUrl){ | ||
| 38 | - baseUrl = url | 44 | + func login(userInfo: UserInfoModel?){ |
| 45 | + if let userInfo{ | ||
| 46 | + myUserInfo = userInfo | ||
| 47 | + return | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + guard let data = AppGroupConstants.defaults?.data(forKey: AppGroupConstants.Key.myUserInfo) else{ | ||
| 51 | + return | ||
| 52 | + } | ||
| 53 | + do{ | ||
| 54 | + myUserInfo = try JSONDecoder().decode(UserInfoModel.self, from: data) | ||
| 55 | + }catch{ | ||
| 56 | + | ||
| 39 | } | 57 | } |
| 40 | } | 58 | } |
| 41 | 59 | ||
| 42 | func logout(){ | 60 | func logout(){ |
| 43 | - token = nil | ||
| 44 | - userId = nil | ||
| 45 | - userSummary = nil | 61 | + myUserInfo = nil |
| 62 | + AppGroupConstants.defaults?.removeObject(forKey: AppGroupConstants.Key.myUserInfo) | ||
| 46 | } | 63 | } |
| 47 | 64 | ||
| 48 | func reportDeviceInfo() async{ | 65 | func reportDeviceInfo() async{ |
| 49 | guard AppShared.shared.isLogin else { | 66 | guard AppShared.shared.isLogin else { |
| 50 | - print("not login") | 67 | + print("reportDeviceInfo not login") |
| 51 | return | 68 | return |
| 52 | } | 69 | } |
| 53 | 70 | ||
| @@ -56,7 +73,7 @@ class AppShared{ | @@ -56,7 +73,7 @@ class AppShared{ | ||
| 56 | print("error invalid baseUrl \(AppShared.shared.baseUrl)") | 73 | print("error invalid baseUrl \(AppShared.shared.baseUrl)") |
| 57 | return | 74 | return |
| 58 | } | 75 | } |
| 59 | - | 76 | + /// 推送平台 choices: [(1, '小米'), (2, '华为'), (3, 'oppo'), (4, 'vivo'), (5, '荣耀'), (100, '苹果')] |
| 60 | var params: [String: String] = ["push_platform": "100"] | 77 | var params: [String: String] = ["push_platform": "100"] |
| 61 | params["device_info"] = AppShared.shared.agent.deviceInfo | 78 | params["device_info"] = AppShared.shared.agent.deviceInfo |
| 62 | params["device_token"] = AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.appDeviceToken) | 79 | params["device_token"] = AppGroupConstants.defaults?.string(forKey: AppGroupConstants.Key.appDeviceToken) |
| @@ -79,8 +96,13 @@ class AppShared{ | @@ -79,8 +96,13 @@ class AppShared{ | ||
| 79 | 96 | ||
| 80 | let bodyText = String(data: data, encoding: .utf8) ?? "" | 97 | let bodyText = String(data: data, encoding: .utf8) ?? "" |
| 81 | print("upload device info status=\(httpResponse.statusCode), body=\(bodyText)") | 98 | print("upload device info status=\(httpResponse.statusCode), body=\(bodyText)") |
| 99 | + | ||
| 100 | + guard (200..<300).contains(httpResponse.statusCode) else { | ||
| 101 | + return | ||
| 102 | + } | ||
| 82 | } catch { | 103 | } catch { |
| 83 | print("upload device info failed: \(error.localizedDescription)") | 104 | print("upload device info failed: \(error.localizedDescription)") |
| 84 | } | 105 | } |
| 106 | + | ||
| 85 | } | 107 | } |
| 86 | } | 108 | } |
| @@ -197,18 +197,18 @@ class ApplePayment { | @@ -197,18 +197,18 @@ class ApplePayment { | ||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | var params: [String: String] = [ | 199 | var params: [String: String] = [ |
| 200 | - "productId": productId, | ||
| 201 | - "appAccountToken": appAccountToken | 200 | + "product_id": productId, |
| 201 | + "app_account_token": appAccountToken | ||
| 202 | ] | 202 | ] |
| 203 | - params["originalTransactionId"] = originalTransactionId | ||
| 204 | - params["transactionId"] = transactionId | 203 | + params["original_transaction_id"] = originalTransactionId |
| 204 | + params["transaction_id"] = transactionId | ||
| 205 | 205 | ||
| 206 | var request = URLRequest(url: url) | 206 | var request = URLRequest(url: url) |
| 207 | request.httpMethod = "POST" | 207 | request.httpMethod = "POST" |
| 208 | request.timeoutInterval = 30 | 208 | request.timeoutInterval = 30 |
| 209 | request.setValue("application/json", forHTTPHeaderField: "Content-Type") | 209 | request.setValue("application/json", forHTTPHeaderField: "Content-Type") |
| 210 | request.setValue("application/json", forHTTPHeaderField: "Accept") | 210 | request.setValue("application/json", forHTTPHeaderField: "Accept") |
| 211 | - request.setValue(AppShared.shared.userSummary?.accessToken, forHTTPHeaderField: "access_token") | 211 | + request.setValue(AppShared.shared.token, forHTTPHeaderField: "access_token") |
| 212 | request.setValue(AppShared.shared.agent.finalUA, forHTTPHeaderField: "User-Agent") | 212 | request.setValue(AppShared.shared.agent.finalUA, forHTTPHeaderField: "User-Agent") |
| 213 | 213 | ||
| 214 | do { | 214 | do { |
| @@ -249,7 +249,7 @@ class ApplePayment { | @@ -249,7 +249,7 @@ class ApplePayment { | ||
| 249 | request.timeoutInterval = 30 | 249 | request.timeoutInterval = 30 |
| 250 | request.setValue("application/json", forHTTPHeaderField: "Content-Type") | 250 | request.setValue("application/json", forHTTPHeaderField: "Content-Type") |
| 251 | request.setValue("application/json", forHTTPHeaderField: "Accept") | 251 | request.setValue("application/json", forHTTPHeaderField: "Accept") |
| 252 | - request.setValue(AppShared.shared.userSummary?.accessToken, forHTTPHeaderField: "access_token") | 252 | + request.setValue(AppShared.shared.token, forHTTPHeaderField: "access_token") |
| 253 | request.setValue(AppShared.shared.agent.finalUA, forHTTPHeaderField: "User-Agent") | 253 | request.setValue(AppShared.shared.agent.finalUA, forHTTPHeaderField: "User-Agent") |
| 254 | 254 | ||
| 255 | do { | 255 | do { |
| @@ -343,8 +343,8 @@ extension ApplePayment { | @@ -343,8 +343,8 @@ extension ApplePayment { | ||
| 343 | return Task.detached { | 343 | return Task.detached { |
| 344 | for await result in Transaction.updates { | 344 | for await result in Transaction.updates { |
| 345 | do { | 345 | do { |
| 346 | - let transaction = try await self.checkVerified(result) | ||
| 347 | - if await AppShared.shared.isLogin{ | 346 | + let transaction = try self.checkVerified(result) |
| 347 | + if AppShared.shared.isLogin{ | ||
| 348 | let success = await self.verifyWithServer(appAccountToken: transaction.appAccountToken?.uuidString ?? "", originalTransactionId: String(transaction.originalID), transactionId: String(transaction.id), productId: transaction.productID) | 348 | let success = await self.verifyWithServer(appAccountToken: transaction.appAccountToken?.uuidString ?? "", originalTransactionId: String(transaction.originalID), transactionId: String(transaction.id), productId: transaction.productID) |
| 349 | // 更新客户产品状态 | 349 | // 更新客户产品状态 |
| 350 | if success{ | 350 | if success{ |
| @@ -6,7 +6,6 @@ | @@ -6,7 +6,6 @@ | ||
| 6 | // | 6 | // |
| 7 | 7 | ||
| 8 | import Foundation | 8 | import Foundation |
| 9 | -import UIKit | ||
| 10 | import WebKit | 9 | import WebKit |
| 11 | 10 | ||
| 12 | extension UIApplication { | 11 | extension UIApplication { |
| @@ -40,10 +39,10 @@ class UserAgent { | @@ -40,10 +39,10 @@ class UserAgent { | ||
| 40 | func customUA() -> String { | 39 | func customUA() -> String { |
| 41 | let version = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) as! NSString | 40 | let version = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) as! NSString |
| 42 | let bundle = Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "" | 41 | let bundle = Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "" |
| 43 | - let hardware = Self.hardwareString() | 42 | + let hardware = hardwareString() |
| 44 | deviceInfo = hardware | 43 | deviceInfo = hardware |
| 45 | AppGroupConstants.defaults?.set(hardware, forKey: AppGroupConstants.Key.deviceInfo) | 44 | AppGroupConstants.defaults?.set(hardware, forKey: AppGroupConstants.Key.deviceInfo) |
| 46 | - | 45 | + |
| 47 | let systemVersion = UIDevice.current.systemVersion | 46 | let systemVersion = UIDevice.current.systemVersion |
| 48 | let height = UIApplication.shared.currentScreen?.bounds.height ?? 0 | 47 | let height = UIApplication.shared.currentScreen?.bounds.height ?? 0 |
| 49 | let width = UIApplication.shared.currentScreen?.bounds.width ?? 0 | 48 | let width = UIApplication.shared.currentScreen?.bounds.width ?? 0 |
| @@ -55,7 +54,7 @@ class UserAgent { | @@ -55,7 +54,7 @@ class UserAgent { | ||
| 55 | return ua | 54 | return ua |
| 56 | } | 55 | } |
| 57 | 56 | ||
| 58 | - private static func hardwareString() -> String { | 57 | + private func hardwareString() -> String { |
| 59 | var systemInfo = utsname() | 58 | var systemInfo = utsname() |
| 60 | uname(&systemInfo) | 59 | uname(&systemInfo) |
| 61 | 60 |
ios/Runner/Shared/UserInfoModel.swift
0 → 100644
| 1 | +// | ||
| 2 | +// UserInfoModel.swift | ||
| 3 | +// hippo | ||
| 4 | +// | ||
| 5 | +// Created by 权海 on 2026/6/26. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +import Foundation | ||
| 9 | + | ||
| 10 | +struct UserInfoModel: Codable, Equatable{ | ||
| 11 | + var userId: Int? | ||
| 12 | + var token: String? | ||
| 13 | + var baseUrl: String? | ||
| 14 | + | ||
| 15 | + init(userId: Int? = nil, token: String? = nil, baseUrl: String? = nil) { | ||
| 16 | + self.userId = userId | ||
| 17 | + self.token = token | ||
| 18 | + self.baseUrl = baseUrl | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + func toJson() -> [String: Any]{ | ||
| 22 | + do{ | ||
| 23 | + let data = try JSONEncoder().encode(self) | ||
| 24 | + return try JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed) as! [String : Any] | ||
| 25 | + }catch{ | ||
| 26 | + return [:] | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + var jsonString: String? { | ||
| 31 | + guard let data = try? JSONEncoder().encode(self) else { | ||
| 32 | + return nil | ||
| 33 | + } | ||
| 34 | + return String(data: data, encoding: .utf8) | ||
| 35 | + } | ||
| 36 | +} |
| @@ -20,7 +20,9 @@ final class WatchConnectivityService: NSObject { | @@ -20,7 +20,9 @@ final class WatchConnectivityService: NSObject { | ||
| 20 | guard WCSession.isSupported() else { return false } | 20 | guard WCSession.isSupported() else { return false } |
| 21 | let session = WCSession.default | 21 | let session = WCSession.default |
| 22 | session.delegate = self | 22 | session.delegate = self |
| 23 | - session.activate() | 23 | + if session.activationState == .notActivated { |
| 24 | + session.activate() | ||
| 25 | + } | ||
| 24 | refreshState() | 26 | refreshState() |
| 25 | return true | 27 | return true |
| 26 | } | 28 | } |
| @@ -55,72 +57,62 @@ final class WatchConnectivityService: NSObject { | @@ -55,72 +57,62 @@ final class WatchConnectivityService: NSObject { | ||
| 55 | ) | 57 | ) |
| 56 | } | 58 | } |
| 57 | 59 | ||
| 58 | - func sendTextMessage(_ message: String) -> Bool { | ||
| 59 | - activate() | ||
| 60 | - guard WCSession.default.isReachable else { return false } | ||
| 61 | - WCSession.default.sendMessage(["message": message], replyHandler: nil) { error in | ||
| 62 | - print("Watch message failed: \(error.localizedDescription)") | 60 | + func transferLoginInfo(userInfo: UserInfoModel?){ |
| 61 | + guard activate() else { return } | ||
| 62 | + let params = loginPayload(userInfo: userInfo) | ||
| 63 | + do{ | ||
| 64 | + try WCSession.default.updateApplicationContext(params) | ||
| 65 | + print("Send Watch updateApplicationContext: \(params)") | ||
| 66 | + }catch{ | ||
| 67 | + print("Error Send Watch updateApplicationContext: \(params)") | ||
| 68 | + } | ||
| 63 | } | 69 | } |
| 64 | - return true | ||
| 65 | - } | ||
| 66 | 70 | ||
| 67 | - func sendCommandMessage(_ message: String) -> Bool { | ||
| 68 | - activate() | ||
| 69 | - guard WCSession.default.isReachable else { return false } | ||
| 70 | - WCSession.default.sendMessage(["command": message], replyHandler: nil) { error in | ||
| 71 | - print("Watch message send failed: \(error.localizedDescription)") | ||
| 72 | - } | ||
| 73 | - return true | ||
| 74 | - } | 71 | + func sendLoginInfoMessage(userInfo: UserInfoModel?) -> Bool { |
| 72 | + guard let userInfo else { | ||
| 73 | + return sendCommandMessage(AppGroupMessageKey.logout) | ||
| 74 | + } | ||
| 75 | 75 | ||
| 76 | - func syncPayload(jsonPayload: String) -> Bool { | ||
| 77 | - activate() | ||
| 78 | - guard let data = jsonPayload.data(using: .utf8), | ||
| 79 | - let object = try? JSONSerialization.jsonObject(with: data), | ||
| 80 | - let payload = object as? [String: Any] else { | ||
| 81 | - return false | 76 | + guard let json = userInfo.jsonString else { |
| 77 | + return false | ||
| 78 | + } | ||
| 79 | + return sendCommandMessage(AppGroupMessageKey.login, json: json) | ||
| 82 | } | 80 | } |
| 83 | 81 | ||
| 84 | - persistThemeIfPresent(payload: payload, originalJSON: jsonPayload) | ||
| 85 | - | ||
| 86 | - guard WCSession.isSupported(), WCSession.default.isPaired, WCSession.default.isWatchAppInstalled else { | ||
| 87 | - return false | 82 | + private func loginPayload(userInfo: UserInfoModel?) -> [String: Any] { |
| 83 | + guard var params = userInfo?.toJson(), !params.isEmpty else { | ||
| 84 | + return ["command": AppGroupMessageKey.logout] | ||
| 85 | + } | ||
| 86 | + params["command"] = AppGroupMessageKey.login | ||
| 87 | + return params | ||
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | - WCSession.default.transferUserInfo(payload) | ||
| 91 | - try? WCSession.default.updateApplicationContext(payload) | ||
| 92 | - sendWatchThemeChangedMessageIfNeeded(payload: payload) | 90 | + func sendTextMessage(_ message: String) -> Bool { |
| 91 | + activate() | ||
| 92 | + guard WCSession.default.isReachable else { return false } | ||
| 93 | + WCSession.default.sendMessage(["message": message], replyHandler: nil) { error in | ||
| 94 | + print("Watch message failed: \(error.localizedDescription)") | ||
| 95 | + } | ||
| 93 | return true | 96 | return true |
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | - func sendWatchThemeChangedMessage() -> Bool { | ||
| 97 | - sendCommandMessage(AppGroupMessageKey.reloadTheme) | ||
| 98 | - } | 99 | + func sendCommandMessage(_ message: String, json: String? = nil) -> Bool { |
| 100 | + activate() | ||
| 101 | + guard WCSession.default.isReachable else { return false } | ||
| 102 | + var params: [String: Any] = [ | ||
| 103 | + "command": message | ||
| 104 | + ] | ||
| 105 | + params["json"] = json | ||
| 99 | 106 | ||
| 100 | - private func sendWatchThemeChangedMessageIfNeeded(payload: [String: Any]) { | ||
| 101 | - if payload["myWatchTheme"] != nil || payload["watchTheme"] != nil || payload["theme"] != nil { | ||
| 102 | - sendWatchThemeChangedMessage() | ||
| 103 | - } | ||
| 104 | - } | ||
| 105 | - | ||
| 106 | - private func persistThemeIfPresent(payload: [String: Any], originalJSON: String) { | ||
| 107 | - if let theme = payload["myWatchTheme"] as? String { | ||
| 108 | - WatchThemeStore.shared.saveThemeJSONString(theme) | ||
| 109 | - return | 107 | + WCSession.default.sendMessage(params, replyHandler: nil) { error in |
| 108 | + print("Watch message send failed: \(error.localizedDescription)") | ||
| 109 | + } | ||
| 110 | + return true | ||
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | - let themeObject = payload["watchTheme"] ?? payload["theme"] | ||
| 113 | - guard let themeObject, | ||
| 114 | - JSONSerialization.isValidJSONObject(themeObject), | ||
| 115 | - let data = try? JSONSerialization.data(withJSONObject: themeObject), | ||
| 116 | - let json = String(data: data, encoding: .utf8) else { | ||
| 117 | - if payload["isWatchTheme"] as? Bool == true { | ||
| 118 | - WatchThemeStore.shared.saveThemeJSONString(originalJSON) | ||
| 119 | - } | ||
| 120 | - return | 113 | + func sendWatchThemeChangedMessage(json: String) -> Bool{ |
| 114 | + sendCommandMessage(AppGroupMessageKey.reloadTheme, json: json) | ||
| 121 | } | 115 | } |
| 122 | - WatchThemeStore.shared.saveThemeJSONString(json) | ||
| 123 | - } | ||
| 124 | } | 116 | } |
| 125 | 117 | ||
| 126 | extension WatchConnectivityService: WCSessionDelegate { | 118 | extension WatchConnectivityService: WCSessionDelegate { |
| @@ -132,6 +124,8 @@ extension WatchConnectivityService: WCSessionDelegate { | @@ -132,6 +124,8 @@ extension WatchConnectivityService: WCSessionDelegate { | ||
| 132 | refreshState() | 124 | refreshState() |
| 133 | if let error { | 125 | if let error { |
| 134 | print("WatchConnectivity activation failed: \(error.localizedDescription)") | 126 | print("WatchConnectivity activation failed: \(error.localizedDescription)") |
| 127 | + }else{ | ||
| 128 | + transferLoginInfo(userInfo: AppShared.shared.myUserInfo) | ||
| 135 | } | 129 | } |
| 136 | } | 130 | } |
| 137 | 131 | ||
| @@ -146,12 +140,17 @@ extension WatchConnectivityService: WCSessionDelegate { | @@ -146,12 +140,17 @@ extension WatchConnectivityService: WCSessionDelegate { | ||
| 146 | 140 | ||
| 147 | func sessionReachabilityDidChange(_ session: WCSession) { | 141 | func sessionReachabilityDidChange(_ session: WCSession) { |
| 148 | refreshState() | 142 | refreshState() |
| 143 | + if session.isReachable { | ||
| 144 | + _ = sendLoginInfoMessage(userInfo: AppShared.shared.myUserInfo) | ||
| 145 | + } | ||
| 149 | } | 146 | } |
| 150 | 147 | ||
| 151 | func session(_ session: WCSession, didReceiveMessage message: [String: Any]) { | 148 | func session(_ session: WCSession, didReceiveMessage message: [String: Any]) { |
| 152 | - if message["command"] as? String == "statusPulseRefresh" { | 149 | + if message["command"] as? String == AppGroupMessageKey.watchDeviceToken, |
| 150 | + let token = message["token"] as? String { | ||
| 151 | + AppGroupConstants.defaults?.set(token, forKey: AppGroupConstants.Key.watchDeviceToken) | ||
| 153 | Task { | 152 | Task { |
| 154 | - await HealthKitService.shared.refreshSharedWatchValues() | 153 | + await AppShared.shared.reportDeviceInfo() |
| 155 | } | 154 | } |
| 156 | } | 155 | } |
| 157 | } | 156 | } |
| @@ -161,11 +160,22 @@ extension WatchConnectivityService: WCSessionDelegate { | @@ -161,11 +160,22 @@ extension WatchConnectivityService: WCSessionDelegate { | ||
| 161 | didReceiveMessage message: [String: Any], | 160 | didReceiveMessage message: [String: Any], |
| 162 | replyHandler: @escaping ([String: Any]) -> Void | 161 | replyHandler: @escaping ([String: Any]) -> Void |
| 163 | ) { | 162 | ) { |
| 164 | - if message["command"] as? String == "statusPulseRefresh" { | 163 | + if message["command"] as? String == AppGroupMessageKey.requestLoginState { |
| 164 | + let userInfo = AppShared.shared.myUserInfo | ||
| 165 | + var reply = loginPayload(userInfo: userInfo) | ||
| 166 | + if let userInfo, let json = userInfo.jsonString { | ||
| 167 | + reply["json"] = json | ||
| 168 | + } | ||
| 169 | + replyHandler(reply) | ||
| 170 | + } else if message["command"] as? String == AppGroupMessageKey.watchDeviceToken, | ||
| 171 | + let token = message["token"] as? String { | ||
| 172 | + AppGroupConstants.defaults?.set(token, forKey: AppGroupConstants.Key.watchDeviceToken) | ||
| 165 | Task { | 173 | Task { |
| 166 | - await HealthKitService.shared.refreshSharedWatchValues() | ||
| 167 | - replyHandler(["success": true]) | 174 | + await AppShared.shared.reportDeviceInfo() |
| 168 | } | 175 | } |
| 176 | + replyHandler(["success": true]) | ||
| 177 | + } else if message["command"] as? String == AppGroupMessageKey.statusPulseRefresh { | ||
| 178 | + replyHandler(["success": true]) | ||
| 169 | } else { | 179 | } else { |
| 170 | replyHandler(["success": true]) | 180 | replyHandler(["success": true]) |
| 171 | } | 181 | } |
-
Please register or login to post a comment