DFWatchThemeStore.swift
4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// DFWatchThemeStore.swift
// hippo-watch-extension
//
import Foundation
import SwiftUI
enum DFWatchThemeStore {
static func currentTheme() async -> WatchLocalTheme? {
if let localTheme = storedTheme() {
if localTheme.hasAllImages {
return localTheme
}
guard let remoteTheme = await remoteTheme() else {
return localTheme
}
let refreshedTheme = await WatchThemeLocalBuilder.makeLocalTheme(from: remoteTheme)
save(refreshedTheme)
return refreshedTheme
}
if let remoteTheme = await remoteTheme() {
let localTheme = await WatchThemeLocalBuilder.makeLocalTheme(from: remoteTheme)
save(localTheme)
return localTheme
}
guard let legacyTheme = legacyRemoteTheme() else {
return nil
}
let localTheme = await WatchThemeLocalBuilder.makeLocalTheme(from: legacyTheme)
save(localTheme)
return localTheme
}
private static func storedTheme() -> WatchLocalTheme? {
guard let data = AppGroupConstants.defaults?.data(
forKey: AppGroupConstants.Key.myWatchTheme
) else {
return nil
}
if let theme = try? JSONDecoder().decode(WatchLocalTheme.self, from: data) {
return theme
}
return nil
}
private static func legacyRemoteTheme() -> WatchThemeModel? {
if let data = AppGroupConstants.defaults?.data(
forKey: AppGroupConstants.Key.myWatchTheme
),
let theme = try? JSONDecoder().decode(WatchThemeModel.self, from: data) {
return theme
}
if let jsonString = AppGroupConstants.defaults?.string(
forKey: AppGroupConstants.Key.myWatchTheme
),
let data = jsonString.data(using: .utf8),
let theme = try? JSONDecoder().decode(WatchThemeModel.self, from: data) {
return theme
}
return nil
}
private static func save(_ theme: WatchLocalTheme) {
guard let data = try? JSONEncoder().encode(theme) else { return }
AppGroupConstants.defaults?.set(data, forKey: AppGroupConstants.Key.myWatchTheme)
}
private static func remoteTheme() async -> WatchThemeModel? {
guard let login = loginInfo(),
let token = login.token,
!token.isEmpty else {
return nil
}
let baseUrl = login.baseUrl ?? "https://api.doublefeel.cn"
guard let url = URL(
string: baseUrl + "/client/doublefeel/theme/v2/watch_theme/active/"
) else {
return nil
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue(token, forHTTPHeaderField: "access_token")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200..<300).contains(httpResponse.statusCode) else {
return nil
}
return try JSONDecoder().decode(WatchThemeModel.self, from: data)
} catch {
return nil
}
}
private static func loginInfo() -> UserInfoModel? {
guard let data = AppGroupConstants.defaults?.data(
forKey: AppGroupConstants.Key.myUserInfo
) else {
return nil
}
return try? JSONDecoder().decode(UserInfoModel.self, from: data)
}
}
extension WatchLocalTheme {
func faceContent(for status: DFStressStatus) -> (title: String, image: Image?) {
let title: String
let data: Data?
switch status {
case .excellent:
title = energeticDescription
data = energeticImage
case .normal:
title = normalDescription
data = normalImage
case .little:
title = slightStressfulDescription
data = slightStressfulImage
case .overloaded:
title = stressfulDescription
data = stressfulImage
}
guard let data, let uiImage = UIImage(data: data) else {
return (title, nil)
}
return (title, Image(uiImage: uiImage))
}
}