@blueid/access-capacitor 0.101.0 → 0.104.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/CBlueIDAccess.xcframework/Info.plist +8 -8
- package/ios/CBlueIDAccess.xcframework/ios-arm64/libCBlueIDAccess.a +0 -0
- package/ios/CBlueIDAccess.xcframework/ios-arm64_x86_64-simulator/libCBlueIDAccess.a +0 -0
- package/ios/CBlueIDAccess.xcframework/macos-arm64_x86_64/libCBlueIDAccess.a +0 -0
- package/ios/Plugin/BlueIDAccessSDK/BlueAccessSync.swift +2 -2
- package/ios/Plugin/BlueIDAccessSDK/BlueAccessSyncScheduler.swift +4 -6
- package/ios/Plugin/BlueIDAccessSDK/BlueModal/BlueSynchronizeAccessDeviceModalView.swift +74 -58
- package/ios/Plugin/BlueIDAccessSDK/BlueTaskRunner.swift +1 -1
- package/ios/Plugin/BlueIDAccessSDK/Extensions.swift +35 -14
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<key>HeadersPath</key>
|
|
11
11
|
<string>Headers</string>
|
|
12
12
|
<key>LibraryIdentifier</key>
|
|
13
|
-
<string>
|
|
13
|
+
<string>macos-arm64_x86_64</string>
|
|
14
14
|
<key>LibraryPath</key>
|
|
15
15
|
<string>libCBlueIDAccess.a</string>
|
|
16
16
|
<key>SupportedArchitectures</key>
|
|
@@ -19,9 +19,7 @@
|
|
|
19
19
|
<string>x86_64</string>
|
|
20
20
|
</array>
|
|
21
21
|
<key>SupportedPlatform</key>
|
|
22
|
-
<string>
|
|
23
|
-
<key>SupportedPlatformVariant</key>
|
|
24
|
-
<string>simulator</string>
|
|
22
|
+
<string>macos</string>
|
|
25
23
|
</dict>
|
|
26
24
|
<dict>
|
|
27
25
|
<key>BinaryPath</key>
|
|
@@ -29,16 +27,15 @@
|
|
|
29
27
|
<key>HeadersPath</key>
|
|
30
28
|
<string>Headers</string>
|
|
31
29
|
<key>LibraryIdentifier</key>
|
|
32
|
-
<string>
|
|
30
|
+
<string>ios-arm64</string>
|
|
33
31
|
<key>LibraryPath</key>
|
|
34
32
|
<string>libCBlueIDAccess.a</string>
|
|
35
33
|
<key>SupportedArchitectures</key>
|
|
36
34
|
<array>
|
|
37
35
|
<string>arm64</string>
|
|
38
|
-
<string>x86_64</string>
|
|
39
36
|
</array>
|
|
40
37
|
<key>SupportedPlatform</key>
|
|
41
|
-
<string>
|
|
38
|
+
<string>ios</string>
|
|
42
39
|
</dict>
|
|
43
40
|
<dict>
|
|
44
41
|
<key>BinaryPath</key>
|
|
@@ -46,15 +43,18 @@
|
|
|
46
43
|
<key>HeadersPath</key>
|
|
47
44
|
<string>Headers</string>
|
|
48
45
|
<key>LibraryIdentifier</key>
|
|
49
|
-
<string>ios-
|
|
46
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
50
47
|
<key>LibraryPath</key>
|
|
51
48
|
<string>libCBlueIDAccess.a</string>
|
|
52
49
|
<key>SupportedArchitectures</key>
|
|
53
50
|
<array>
|
|
54
51
|
<string>arm64</string>
|
|
52
|
+
<string>x86_64</string>
|
|
55
53
|
</array>
|
|
56
54
|
<key>SupportedPlatform</key>
|
|
57
55
|
<string>ios</string>
|
|
56
|
+
<key>SupportedPlatformVariant</key>
|
|
57
|
+
<string>simulator</string>
|
|
58
58
|
</dict>
|
|
59
59
|
</array>
|
|
60
60
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -39,7 +39,7 @@ internal class BlueAbstractSynchronizeAccessCommand<T>: BlueSdkAsyncCommand wher
|
|
|
39
39
|
|
|
40
40
|
guard let response = try? await self.sync(with: tokenAuthentication, forceRefresh: forceRefresh) else {
|
|
41
41
|
if (credential.hasValidTo) {
|
|
42
|
-
if let validTo = credential.validTo.
|
|
42
|
+
if let validTo = credential.validTo.toUTCDate() {
|
|
43
43
|
|
|
44
44
|
let isExpired = validTo < Date()
|
|
45
45
|
if (isExpired) {
|
|
@@ -128,7 +128,7 @@ internal class BlueSynchronizeMobileAccessCommand: BlueAbstractSynchronizeAccess
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
if let validity = synchronizationResult.validity {
|
|
131
|
-
updatedCredential.validity = BlueLocalTimestamp(Date(timeIntervalSince1970: TimeInterval(validity/1000)))
|
|
131
|
+
updatedCredential.validity = BlueLocalTimestamp.fromUTCDate(Date(timeIntervalSince1970: TimeInterval(validity/1000)))
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
try blueAccessCredentialsKeyChain.updateEntry(id: updatedCredential.credentialID.id, data: updatedCredential.jsonUTF8Data())
|
|
@@ -109,8 +109,6 @@ internal class BlueAccessSyncScheduler: BlueEventListener {
|
|
|
109
109
|
blueLogError(error.localizedDescription)
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
blueRemoveEventListener(listener: self)
|
|
113
|
-
|
|
114
112
|
foregroundScheduler.schedule(now)
|
|
115
113
|
}
|
|
116
114
|
|
|
@@ -143,10 +141,10 @@ internal class BlueAccessSyncScheduler: BlueEventListener {
|
|
|
143
141
|
if let credentials = try? blueCommands.getAccessCredentials.run().credentials {
|
|
144
142
|
if (!credentials.isEmpty) {
|
|
145
143
|
credentials.forEach { credential in
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
let now = now ?? Date()
|
|
145
|
+
|
|
146
|
+
if (!credential.checkValidityStart(now)) {
|
|
147
|
+
if let validFrom = credential.validFrom.toUTCDate() {
|
|
150
148
|
if validFrom > now {
|
|
151
149
|
let differenceInSeconds = validFrom.timeIntervalSince(now)
|
|
152
150
|
|
|
@@ -13,14 +13,14 @@ private func getColor(_ status: BlueTaskStatus) -> Color {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
private func
|
|
16
|
+
private func getTextColor(_ status: BlueTaskStatus) -> Color {
|
|
17
17
|
switch (status) {
|
|
18
|
-
case .ready, .started:
|
|
19
|
-
return .
|
|
20
|
-
case .
|
|
21
|
-
return .
|
|
22
|
-
|
|
23
|
-
return
|
|
18
|
+
case .ready, .started, .skipped:
|
|
19
|
+
return .black
|
|
20
|
+
case .succeeded:
|
|
21
|
+
return Color(red: 0.0, green: 0.5, blue: 0.0)
|
|
22
|
+
default:
|
|
23
|
+
return getColor(status)
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -32,8 +32,10 @@ private func getSymbol(_ status: BlueTaskStatus) -> String {
|
|
|
32
32
|
return "circle.circle"
|
|
33
33
|
case .failed:
|
|
34
34
|
return "xmark.circle"
|
|
35
|
-
case .succeeded
|
|
35
|
+
case .succeeded:
|
|
36
36
|
return "checkmark.circle"
|
|
37
|
+
case .skipped:
|
|
38
|
+
return "minus.circle"
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -41,7 +43,7 @@ class BlueTaskModel: ObservableObject, Identifiable {
|
|
|
41
43
|
@Published var label: String
|
|
42
44
|
@Published var status: BlueTaskStatus
|
|
43
45
|
@Published var statusColor: Color
|
|
44
|
-
@Published var
|
|
46
|
+
@Published var textColor: Color
|
|
45
47
|
@Published var symbol: String
|
|
46
48
|
@Published var errorDescription: String
|
|
47
49
|
@Published var isLast: Bool
|
|
@@ -51,8 +53,8 @@ class BlueTaskModel: ObservableObject, Identifiable {
|
|
|
51
53
|
init(_ task: BlueTask, _ isLast: Bool) {
|
|
52
54
|
self.label = task.label
|
|
53
55
|
self.status = task.status.value
|
|
56
|
+
self.textColor = getTextColor(task.status.value)
|
|
54
57
|
self.statusColor = getColor(task.status.value)
|
|
55
|
-
self.lineColor = getLineColor(task.status.value)
|
|
56
58
|
self.symbol = getSymbol(task.status.value)
|
|
57
59
|
self.errorDescription = task.errorDescription ?? ""
|
|
58
60
|
self.isLast = isLast
|
|
@@ -61,8 +63,8 @@ class BlueTaskModel: ObservableObject, Identifiable {
|
|
|
61
63
|
guard let self = self else { return }
|
|
62
64
|
|
|
63
65
|
self.status = status
|
|
66
|
+
self.textColor = getTextColor(status)
|
|
64
67
|
self.statusColor = getColor(status)
|
|
65
|
-
self.lineColor = getLineColor(status)
|
|
66
68
|
self.symbol = getSymbol(status)
|
|
67
69
|
self.errorDescription = task.errorDescription ?? ""
|
|
68
70
|
|
|
@@ -90,23 +92,27 @@ struct TaskView: View {
|
|
|
90
92
|
|
|
91
93
|
Text(task.label)
|
|
92
94
|
.font(.system(size: 14))
|
|
95
|
+
.foregroundColor(task.textColor)
|
|
93
96
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
HStack(alignment: .center) {
|
|
97
|
-
|
|
99
|
+
HStack(alignment: .center, spacing: 0) {
|
|
100
|
+
ZStack(alignment: .leading) {
|
|
98
101
|
Rectangle()
|
|
99
|
-
.fill(task.
|
|
102
|
+
.fill(task.statusColor)
|
|
100
103
|
.frame(width: 2)
|
|
101
104
|
.padding(.horizontal, 10.5)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
.hidden(task.isLast)
|
|
106
|
+
|
|
107
|
+
if !task.errorDescription.isEmpty {
|
|
108
|
+
Text(task.errorDescription)
|
|
109
|
+
.foregroundColor(.red)
|
|
110
|
+
.font(.system(size: 11))
|
|
111
|
+
.padding(.leading, 32)
|
|
112
|
+
.padding(.bottom, 5)
|
|
113
|
+
.fixedSize(horizontal: false, vertical: true)
|
|
114
|
+
.alignmentGuide(.leading) { d in d[.leading] }
|
|
115
|
+
}
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
}
|
|
@@ -119,9 +125,10 @@ class BlueSynchronizeAccessDeviceModalViewModel: ObservableObject {
|
|
|
119
125
|
@Published var dismissEnabled: Bool = true
|
|
120
126
|
@Published var tasks: [BlueTask]
|
|
121
127
|
|
|
122
|
-
init(title: String = "", dismiss: String = "", tasks: [BlueTask] = []) {
|
|
128
|
+
init(title: String = "", dismiss: String = "", dismissEnabled: Bool = true, tasks: [BlueTask] = []) {
|
|
123
129
|
self.title = title
|
|
124
130
|
self.dismiss = dismiss
|
|
131
|
+
self.dismissEnabled = dismissEnabled
|
|
125
132
|
self.tasks = tasks
|
|
126
133
|
}
|
|
127
134
|
}
|
|
@@ -129,7 +136,7 @@ class BlueSynchronizeAccessDeviceModalViewModel: ObservableObject {
|
|
|
129
136
|
struct BlueSynchronizeAccessDeviceModalView: View {
|
|
130
137
|
@ObservedObject private var vm: BlueSynchronizeAccessDeviceModalViewModel
|
|
131
138
|
|
|
132
|
-
internal var height: CGFloat =
|
|
139
|
+
internal var height: CGFloat = 550
|
|
133
140
|
internal var backgroundColor: UIColor = .white
|
|
134
141
|
internal var foregroundColor: UIColor = .black
|
|
135
142
|
|
|
@@ -155,24 +162,30 @@ struct BlueSynchronizeAccessDeviceModalView: View {
|
|
|
155
162
|
.foregroundColor(Color(backgroundColor))
|
|
156
163
|
.shadow(color: .gray, radius: 1)
|
|
157
164
|
|
|
158
|
-
VStack(alignment: .center) {
|
|
165
|
+
VStack(alignment: .center, spacing: 0) {
|
|
159
166
|
Text(vm.title)
|
|
160
167
|
.font(.system(size: 20))
|
|
161
168
|
.foregroundColor(.gray)
|
|
169
|
+
.multilineTextAlignment(.center)
|
|
162
170
|
|
|
163
171
|
Spacer()
|
|
164
172
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
173
|
+
GeometryReader { geometry in
|
|
174
|
+
ScrollView(.vertical) {
|
|
175
|
+
VStack(alignment: .leading, spacing: 0) {
|
|
176
|
+
ForEach(vm.tasks.indices, id: \.self){ index in
|
|
177
|
+
TaskView(task: BlueTaskModel(vm.tasks[index], index == vm.tasks.indices.last))
|
|
178
|
+
}
|
|
169
179
|
}
|
|
170
|
-
|
|
180
|
+
.padding(.vertical, 10)
|
|
181
|
+
.frame(width: geometry.size.width)
|
|
182
|
+
.frame(minHeight: geometry.size.height)
|
|
183
|
+
}
|
|
171
184
|
}
|
|
172
185
|
|
|
186
|
+
Spacer()
|
|
187
|
+
|
|
173
188
|
if !vm.dismiss.isEmpty {
|
|
174
|
-
Spacer()
|
|
175
|
-
|
|
176
189
|
Button {
|
|
177
190
|
onDismiss()
|
|
178
191
|
} label: {
|
|
@@ -180,7 +193,8 @@ struct BlueSynchronizeAccessDeviceModalView: View {
|
|
|
180
193
|
.font(.system(size: 18))
|
|
181
194
|
.frame(maxWidth: .infinity)
|
|
182
195
|
.padding(EdgeInsets(top: 15, leading: 10, bottom: 15, trailing: 10))
|
|
183
|
-
.background(Color.gray.opacity(0.5))
|
|
196
|
+
.background(Color.gray.opacity(vm.dismissEnabled ? 0.5 : 0.3))
|
|
197
|
+
.foregroundColor(vm.dismissEnabled ? .black : .gray)
|
|
184
198
|
.cornerRadius(10)
|
|
185
199
|
}
|
|
186
200
|
.disabled(!vm.dismissEnabled)
|
|
@@ -198,38 +212,40 @@ struct BlueSynchronizeAccessDeviceModalView: View {
|
|
|
198
212
|
}
|
|
199
213
|
}
|
|
200
214
|
|
|
215
|
+
let noop: (BlueSerialTaskRunner) async throws -> BlueTaskResult = { _ in .result(nil) }
|
|
216
|
+
|
|
201
217
|
struct BlueSynchronizeAccessDeviceModalView_Preview: PreviewProvider {
|
|
202
218
|
static var previews: some View {
|
|
203
219
|
BlueSynchronizeAccessDeviceModalView(
|
|
204
220
|
BlueSynchronizeAccessDeviceModalViewModel(
|
|
205
|
-
title: "Synchronization
|
|
206
|
-
dismiss: "
|
|
207
|
-
tasks:
|
|
221
|
+
title: "Synchronization has failed (Worst case)",
|
|
222
|
+
dismiss: "Done",
|
|
223
|
+
tasks: Array(1..<12).map { element in
|
|
208
224
|
BlueTask(
|
|
209
|
-
id:
|
|
210
|
-
label: "
|
|
225
|
+
id: element.description,
|
|
226
|
+
label: "Task label - \(element.description)",
|
|
211
227
|
status: .failed,
|
|
212
|
-
error: BlueError(.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
) { _ in .result(nil) },
|
|
226
|
-
|
|
228
|
+
error: BlueError(.sdkDecodeJsonFailed, cause: BlueError(.sdkNetworkError), detail: "Something went wrong ¯\\_(ツ)_/¯"),
|
|
229
|
+
handler: noop
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
)
|
|
233
|
+
) {}
|
|
234
|
+
|
|
235
|
+
BlueSynchronizeAccessDeviceModalView(
|
|
236
|
+
BlueSynchronizeAccessDeviceModalViewModel(
|
|
237
|
+
title: "Cancelling...",
|
|
238
|
+
dismiss: "Cancel",
|
|
239
|
+
dismissEnabled: false,
|
|
240
|
+
tasks: Array(1..<12).enumerated().map { (index, element) in
|
|
227
241
|
BlueTask(
|
|
228
|
-
id:
|
|
229
|
-
label: "
|
|
230
|
-
status: .
|
|
231
|
-
|
|
232
|
-
|
|
242
|
+
id: element.description,
|
|
243
|
+
label: "Task label - \(element.description)",
|
|
244
|
+
status: index == 1 ? .failed : .succeeded,
|
|
245
|
+
error: index == 1 ? BlueError(.sdkDecodeJsonFailed, cause: BlueError(.sdkNetworkError), detail: "Something went wrong ¯\\_(ツ)_/¯"): nil,
|
|
246
|
+
handler: noop
|
|
247
|
+
)
|
|
248
|
+
}
|
|
233
249
|
)
|
|
234
250
|
) {}
|
|
235
251
|
}
|
|
@@ -35,7 +35,7 @@ public class BlueTask {
|
|
|
35
35
|
|
|
36
36
|
let handler: (BlueSerialTaskRunner) async throws -> BlueTaskResult
|
|
37
37
|
|
|
38
|
-
init(id: AnyHashable, label: String, failable: Bool = false, status: BlueTaskStatus = .ready, error: Error? = nil,
|
|
38
|
+
init(id: AnyHashable, label: String, failable: Bool = false, status: BlueTaskStatus = .ready, error: Error? = nil, handler: @escaping (BlueSerialTaskRunner) async throws -> BlueTaskResult) {
|
|
39
39
|
self.id = id
|
|
40
40
|
self.label = label
|
|
41
41
|
self.failable = failable
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
3
|
extension BlueLocalTimestamp: Encodable, Decodable {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
/// Converts a given UTC Date into a BlueLocalTimestamp.
|
|
6
|
+
///
|
|
7
|
+
/// - returns: The BlueLocalTimestamp
|
|
8
|
+
static public func fromUTCDate(_ date: Date) -> BlueLocalTimestamp {
|
|
9
|
+
var calendar = Calendar(identifier: .gregorian)
|
|
10
|
+
calendar.timeZone = TimeZone(identifier: "UTC")!
|
|
6
11
|
|
|
7
|
-
let calendar = Calendar.current
|
|
8
12
|
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
var instance = BlueLocalTimestamp()
|
|
15
|
+
|
|
16
|
+
instance.year = UInt32(components.year!)
|
|
17
|
+
instance.month = UInt32(components.month!)
|
|
18
|
+
instance.date = UInt32(components.day!)
|
|
19
|
+
instance.hours = UInt32(components.hour!)
|
|
20
|
+
instance.minutes = UInt32(components.minute!)
|
|
21
|
+
instance.seconds = UInt32(components.second!)
|
|
22
|
+
|
|
23
|
+
return instance
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
public init(_ year: Int, _ month: Int, _ date: Int = 1, _ hours: Int = 0, _ minutes: Int = 0, _ seconds: Int = 0) {
|
|
@@ -37,7 +45,15 @@ extension BlueLocalTimestamp: Encodable, Decodable {
|
|
|
37
45
|
seconds = try container.decode(UInt32.self, forKey: .seconds)
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
48
|
+
/// Converts the underlying BlueLocalTimestamp into a date in the UTC timezone. If either the timezone cannot be found or the date is invalid, nil is returned.
|
|
49
|
+
///
|
|
50
|
+
/// - returns: The UTC Date if valid.
|
|
51
|
+
public func toUTCDate() -> Date? {
|
|
52
|
+
guard let tz = TimeZone(abbreviation: "UTC") else {
|
|
53
|
+
blueLogWarn("UTC TZ not found")
|
|
54
|
+
return nil
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
var dateComponents = DateComponents()
|
|
42
58
|
dateComponents.year = Int(year)
|
|
43
59
|
dateComponents.month = Int(month)
|
|
@@ -46,7 +62,10 @@ extension BlueLocalTimestamp: Encodable, Decodable {
|
|
|
46
62
|
dateComponents.minute = Int(minutes)
|
|
47
63
|
dateComponents.second = Int(seconds)
|
|
48
64
|
|
|
49
|
-
|
|
65
|
+
var calendar = Calendar(identifier: .gregorian)
|
|
66
|
+
calendar.timeZone = tz
|
|
67
|
+
|
|
68
|
+
let date = calendar.date(from: dateComponents)
|
|
50
69
|
if (date?.timeIntervalSince1970 ?? 0 <= 0) {
|
|
51
70
|
return nil
|
|
52
71
|
}
|
|
@@ -140,10 +159,12 @@ extension BlueAccessCredential: Decodable {
|
|
|
140
159
|
}
|
|
141
160
|
}
|
|
142
161
|
|
|
143
|
-
public func checkValidityStart() -> Bool {
|
|
162
|
+
public func checkValidityStart(_ now: Date? = nil) -> Bool {
|
|
144
163
|
if self.hasValidFrom {
|
|
145
|
-
if let validFrom = self.validFrom.
|
|
146
|
-
|
|
164
|
+
if let validFrom = self.validFrom.toUTCDate() {
|
|
165
|
+
let now = now ?? Date()
|
|
166
|
+
|
|
167
|
+
if validFrom > now {
|
|
147
168
|
return false
|
|
148
169
|
}
|
|
149
170
|
}
|