@blueid/access-capacitor 0.79.0 → 0.80.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/BlueAccessSyncScheduler.swift +145 -0
- package/ios/Plugin/BlueIDAccessSDK/BlueApp.swift +0 -15
- package/ios/Plugin/BlueIDAccessSDK/BlueAppDelegate.swift +4 -4
- package/package.json +1 -1
- package/ios/Plugin/BlueIDAccessSDK/BlueTokenSyncScheduler.swift +0 -265
|
@@ -10,15 +10,18 @@
|
|
|
10
10
|
<key>HeadersPath</key>
|
|
11
11
|
<string>Headers</string>
|
|
12
12
|
<key>LibraryIdentifier</key>
|
|
13
|
-
<string>ios-
|
|
13
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
14
14
|
<key>LibraryPath</key>
|
|
15
15
|
<string>libCBlueIDAccess.a</string>
|
|
16
16
|
<key>SupportedArchitectures</key>
|
|
17
17
|
<array>
|
|
18
18
|
<string>arm64</string>
|
|
19
|
+
<string>x86_64</string>
|
|
19
20
|
</array>
|
|
20
21
|
<key>SupportedPlatform</key>
|
|
21
22
|
<string>ios</string>
|
|
23
|
+
<key>SupportedPlatformVariant</key>
|
|
24
|
+
<string>simulator</string>
|
|
22
25
|
</dict>
|
|
23
26
|
<dict>
|
|
24
27
|
<key>BinaryPath</key>
|
|
@@ -26,16 +29,15 @@
|
|
|
26
29
|
<key>HeadersPath</key>
|
|
27
30
|
<string>Headers</string>
|
|
28
31
|
<key>LibraryIdentifier</key>
|
|
29
|
-
<string>
|
|
32
|
+
<string>ios-arm64</string>
|
|
30
33
|
<key>LibraryPath</key>
|
|
31
34
|
<string>libCBlueIDAccess.a</string>
|
|
32
35
|
<key>SupportedArchitectures</key>
|
|
33
36
|
<array>
|
|
34
37
|
<string>arm64</string>
|
|
35
|
-
<string>x86_64</string>
|
|
36
38
|
</array>
|
|
37
39
|
<key>SupportedPlatform</key>
|
|
38
|
-
<string>
|
|
40
|
+
<string>ios</string>
|
|
39
41
|
</dict>
|
|
40
42
|
<dict>
|
|
41
43
|
<key>BinaryPath</key>
|
|
@@ -43,7 +45,7 @@
|
|
|
43
45
|
<key>HeadersPath</key>
|
|
44
46
|
<string>Headers</string>
|
|
45
47
|
<key>LibraryIdentifier</key>
|
|
46
|
-
<string>
|
|
48
|
+
<string>macos-arm64_x86_64</string>
|
|
47
49
|
<key>LibraryPath</key>
|
|
48
50
|
<string>libCBlueIDAccess.a</string>
|
|
49
51
|
<key>SupportedArchitectures</key>
|
|
@@ -52,9 +54,7 @@
|
|
|
52
54
|
<string>x86_64</string>
|
|
53
55
|
</array>
|
|
54
56
|
<key>SupportedPlatform</key>
|
|
55
|
-
<string>
|
|
56
|
-
<key>SupportedPlatformVariant</key>
|
|
57
|
-
<string>simulator</string>
|
|
57
|
+
<string>macos</string>
|
|
58
58
|
</dict>
|
|
59
59
|
</array>
|
|
60
60
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
private class ForegroundScheduler {
|
|
4
|
+
private var timer: Timer?
|
|
5
|
+
private var scheduler: BlueAccessSyncScheduler?
|
|
6
|
+
|
|
7
|
+
func setup(_ scheduler: BlueAccessSyncScheduler) {
|
|
8
|
+
self.scheduler = scheduler
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
func suspend() {
|
|
12
|
+
timer?.invalidate()
|
|
13
|
+
timer = nil
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func schedule(_ now: Bool? = false) {
|
|
17
|
+
guard #available(macOS 10.15, *) else {
|
|
18
|
+
blueLogWarn("Unsupported platform")
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
suspend()
|
|
23
|
+
|
|
24
|
+
if now == true {
|
|
25
|
+
self.handleTask()
|
|
26
|
+
} else {
|
|
27
|
+
blueRunInMainThread {
|
|
28
|
+
self.timer = Timer.scheduledTimer(
|
|
29
|
+
timeInterval: self.scheduler!.timeInterval,
|
|
30
|
+
target: self,
|
|
31
|
+
selector: #selector(self.handleTask),
|
|
32
|
+
userInfo: nil,
|
|
33
|
+
repeats: false
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@available(macOS 10.15, *)
|
|
40
|
+
@objc private func handleTask() {
|
|
41
|
+
DispatchQueue.global(qos: .background).async {
|
|
42
|
+
Task {
|
|
43
|
+
do {
|
|
44
|
+
try await self.scheduler!.synchronizeAccessCredentials()
|
|
45
|
+
} catch {
|
|
46
|
+
blueLogError(error.localizedDescription)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (self.scheduler!.autoSchedule) {
|
|
50
|
+
self.schedule()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
internal class BlueAccessSyncScheduler: BlueEventListener {
|
|
58
|
+
public static let shared = BlueAccessSyncScheduler()
|
|
59
|
+
|
|
60
|
+
let timeInterval: TimeInterval
|
|
61
|
+
let autoSchedule: Bool
|
|
62
|
+
|
|
63
|
+
private let foregroundScheduler = ForegroundScheduler()
|
|
64
|
+
|
|
65
|
+
private let command: BlueSynchronizeAccessCredentialsCommand
|
|
66
|
+
|
|
67
|
+
private var syncing = false
|
|
68
|
+
|
|
69
|
+
init(
|
|
70
|
+
timeInterval: TimeInterval? = 60 * 60 * 6, // every 6h by default
|
|
71
|
+
autoSchedule: Bool? = true,
|
|
72
|
+
command: BlueSynchronizeAccessCredentialsCommand? = nil
|
|
73
|
+
) {
|
|
74
|
+
self.command = command ?? blueCommands.synchronizeAccessCredentials
|
|
75
|
+
self.timeInterval = timeInterval ?? 60
|
|
76
|
+
self.autoSchedule = autoSchedule ?? true
|
|
77
|
+
|
|
78
|
+
foregroundScheduler.setup(self)
|
|
79
|
+
|
|
80
|
+
blueAddEventListener(listener: self)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
deinit {
|
|
84
|
+
blueRemoveEventListener(listener: self)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
func willResignActive() {
|
|
88
|
+
suspend()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func willTerminate() {
|
|
92
|
+
suspend()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func didBecomeActive() {
|
|
96
|
+
schedule(true)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
func didFinishLaunching() {
|
|
100
|
+
schedule(true)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
func blueEvent(event: BlueEventType, data: Any?) {
|
|
104
|
+
if (event == .accessCredentialAdded) {
|
|
105
|
+
schedule()
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
func schedule(_ now: Bool? = false) {
|
|
110
|
+
do {
|
|
111
|
+
guard try blueAccessCredentialsKeyChain.getNumberOfEntries() > 0 else {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
blueLogError(error.localizedDescription)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
blueRemoveEventListener(listener: self)
|
|
119
|
+
|
|
120
|
+
foregroundScheduler.schedule(now)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
func suspend() {
|
|
124
|
+
foregroundScheduler.suspend()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func synchronizeAccessCredentials() async throws -> Void {
|
|
128
|
+
if (syncing) {
|
|
129
|
+
blueLogInfo("There is already a synchronization in progress")
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
syncing = true
|
|
134
|
+
|
|
135
|
+
blueFireListeners(fireEvent: BlueEventType.tokenSyncStarted, data: nil)
|
|
136
|
+
|
|
137
|
+
defer {
|
|
138
|
+
syncing = false
|
|
139
|
+
|
|
140
|
+
blueFireListeners(fireEvent: BlueEventType.tokenSyncFinished, data: nil)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
_ = try await command.runAsync()
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -40,18 +40,3 @@ public struct BlueOpenAppSettingsCommand: BlueAsyncCommand {
|
|
|
40
40
|
completionHandler(false)
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
internal func blueAppHasLaunchedBefore() -> Bool {
|
|
45
|
-
if let hasLaunchedBefore = hasLaunchedBefore {
|
|
46
|
-
return hasLaunchedBefore
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let result = blueAppStorage.getBool(id: "hasLaunchedBefore")
|
|
50
|
-
if (!result) {
|
|
51
|
-
blueAppStorage.storeBool(id: "hasLaunchedBefore", bool: true)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
hasLaunchedBefore = true
|
|
55
|
-
|
|
56
|
-
return result
|
|
57
|
-
}
|
|
@@ -18,7 +18,7 @@ public final class BlueAppDelegate: NSObject {
|
|
|
18
18
|
}
|
|
19
19
|
#endif
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
BlueAccessSyncScheduler.shared.didFinishLaunching()
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
#if os(iOS) || os(watchOS)
|
|
@@ -38,7 +38,7 @@ public final class BlueAppDelegate: NSObject {
|
|
|
38
38
|
#endif
|
|
39
39
|
|
|
40
40
|
@objc public static func willResignActive() {
|
|
41
|
-
|
|
41
|
+
BlueAccessSyncScheduler.shared.willResignActive()
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
@objc public static func didBecomeActive() {
|
|
@@ -46,7 +46,7 @@ public final class BlueAppDelegate: NSObject {
|
|
|
46
46
|
blueNearbyAppBecameActive()
|
|
47
47
|
#endif
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
BlueAccessSyncScheduler.shared.didBecomeActive()
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
@objc public static func didEnterBackground() {
|
|
@@ -62,6 +62,6 @@ public final class BlueAppDelegate: NSObject {
|
|
|
62
62
|
fatalError(error.localizedDescription)
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
BlueAccessSyncScheduler.shared.willTerminate()
|
|
66
66
|
}
|
|
67
67
|
}
|
package/package.json
CHANGED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// BlueTokenSyncScheduler.swift
|
|
3
|
-
//
|
|
4
|
-
// Description: Synchronize all tokens from all available credentials at specific intervals.
|
|
5
|
-
//
|
|
6
|
-
// If you would like to test the background task during development, execute the following code in the console:
|
|
7
|
-
// ```
|
|
8
|
-
// e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.blue-id.BlueTokenSyncScheduler"]
|
|
9
|
-
// ```
|
|
10
|
-
//
|
|
11
|
-
// Reference: https://developer.apple.com/documentation/backgroundtasks/starting-and-terminating-tasks-during-development#Launch-a-Task
|
|
12
|
-
//
|
|
13
|
-
// Copyright © 2023 BlueID. All rights reserved.
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
import Foundation
|
|
17
|
-
|
|
18
|
-
private let bgTaskIdentifier = "com.blue-id.BlueTokenSyncScheduler"
|
|
19
|
-
|
|
20
|
-
private class ForegroundScheduler {
|
|
21
|
-
private var timer: Timer?
|
|
22
|
-
private var scheduler: BlueTokenSyncScheduler?
|
|
23
|
-
|
|
24
|
-
func setup(_ scheduler: BlueTokenSyncScheduler) {
|
|
25
|
-
self.scheduler = scheduler
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
func suspend() {
|
|
29
|
-
timer?.invalidate()
|
|
30
|
-
timer = nil
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
func schedule(_ now: Bool? = false) {
|
|
34
|
-
guard #available(macOS 10.15, *) else {
|
|
35
|
-
blueLogWarn("Unsupported platform")
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
suspend()
|
|
40
|
-
|
|
41
|
-
if now == true {
|
|
42
|
-
self.handleTask()
|
|
43
|
-
} else {
|
|
44
|
-
blueRunInMainThread {
|
|
45
|
-
self.timer = Timer.scheduledTimer(
|
|
46
|
-
timeInterval: self.scheduler!.timeInterval,
|
|
47
|
-
target: self,
|
|
48
|
-
selector: #selector(self.handleTask),
|
|
49
|
-
userInfo: nil,
|
|
50
|
-
repeats: false
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@available(macOS 10.15, *)
|
|
57
|
-
@objc private func handleTask() {
|
|
58
|
-
DispatchQueue.global(qos: .background).async {
|
|
59
|
-
Task {
|
|
60
|
-
do {
|
|
61
|
-
try await self.scheduler!.syncTokens()
|
|
62
|
-
} catch {
|
|
63
|
-
blueLogError("Tokens could not be synchronized")
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (self.scheduler!.autoSchedule) {
|
|
67
|
-
self.schedule()
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
#if os(iOS) || os(watchOS)
|
|
76
|
-
import BackgroundTasks
|
|
77
|
-
|
|
78
|
-
private class BackgroundScheduler {
|
|
79
|
-
private var scheduler: BlueTokenSyncScheduler?
|
|
80
|
-
|
|
81
|
-
func setup(_ scheduler: BlueTokenSyncScheduler) {
|
|
82
|
-
self.scheduler = scheduler
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
func registerIdentifiers() {
|
|
86
|
-
let registered = BGTaskScheduler.shared.register(forTaskWithIdentifier: bgTaskIdentifier, using: DispatchQueue.global()) { task in
|
|
87
|
-
self.handleTask(task: task as! BGProcessingTask)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (!registered) {
|
|
91
|
-
blueLogWarn("Could not register background task identifier: \(bgTaskIdentifier)")
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
blueLogDebug("Background task identifier has been successfully registered: \(bgTaskIdentifier)")
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
func suspend() {
|
|
99
|
-
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: bgTaskIdentifier)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
func schedule() {
|
|
103
|
-
do {
|
|
104
|
-
let request = BGProcessingTaskRequest(identifier: bgTaskIdentifier)
|
|
105
|
-
request.earliestBeginDate = Date(timeIntervalSinceNow: scheduler!.timeInterval)
|
|
106
|
-
request.requiresNetworkConnectivity = true
|
|
107
|
-
|
|
108
|
-
try BGTaskScheduler.shared.submit(request)
|
|
109
|
-
|
|
110
|
-
blueLogDebug("Background task has been successfully scheduled")
|
|
111
|
-
} catch {
|
|
112
|
-
blueLogError("Background task could not be scheduled: \(error)")
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private func handleTask(task: BGProcessingTask) -> Void {
|
|
117
|
-
task.expirationHandler = {
|
|
118
|
-
task.setTaskCompleted(success: false)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
Task {
|
|
122
|
-
do {
|
|
123
|
-
try await scheduler!.syncTokens()
|
|
124
|
-
|
|
125
|
-
task.setTaskCompleted(success: true)
|
|
126
|
-
} catch {
|
|
127
|
-
task.setTaskCompleted(success: false)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (scheduler!.autoSchedule) {
|
|
131
|
-
schedule()
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
#endif
|
|
137
|
-
|
|
138
|
-
internal class BlueTokenSyncScheduler: BlueEventListener {
|
|
139
|
-
public static let shared = BlueTokenSyncScheduler()
|
|
140
|
-
|
|
141
|
-
let timeInterval: TimeInterval
|
|
142
|
-
let autoSchedule: Bool
|
|
143
|
-
|
|
144
|
-
#if os(iOS) || os(watchOS)
|
|
145
|
-
private let backgroundScheduler = BackgroundScheduler()
|
|
146
|
-
#endif
|
|
147
|
-
|
|
148
|
-
private let foregroundScheduler = ForegroundScheduler()
|
|
149
|
-
|
|
150
|
-
private let command: BlueSynchronizeAccessCredentialCommand
|
|
151
|
-
|
|
152
|
-
init(
|
|
153
|
-
timeInterval: TimeInterval? = 60,
|
|
154
|
-
autoSchedule: Bool? = true,
|
|
155
|
-
command: BlueSynchronizeAccessCredentialCommand? = nil
|
|
156
|
-
) {
|
|
157
|
-
self.command = command ?? blueCommands.synchronizeAccessCredential
|
|
158
|
-
self.timeInterval = timeInterval ?? 60
|
|
159
|
-
self.autoSchedule = autoSchedule ?? true
|
|
160
|
-
|
|
161
|
-
foregroundScheduler.setup(self)
|
|
162
|
-
|
|
163
|
-
#if os(iOS) || os(watchOS)
|
|
164
|
-
backgroundScheduler.setup(self)
|
|
165
|
-
#endif
|
|
166
|
-
|
|
167
|
-
blueAddEventListener(listener: self)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
deinit {
|
|
171
|
-
blueRemoveEventListener(listener: self)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
func willResignActive() {
|
|
175
|
-
foregroundScheduler.suspend()
|
|
176
|
-
|
|
177
|
-
#if os(iOS) || os(watchOS)
|
|
178
|
-
backgroundScheduler.schedule()
|
|
179
|
-
#endif
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
func didBecomeActive() {
|
|
183
|
-
#if os(iOS) || os(watchOS)
|
|
184
|
-
backgroundScheduler.suspend()
|
|
185
|
-
#endif
|
|
186
|
-
|
|
187
|
-
foregroundScheduler.schedule()
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
func didFinishLaunching() {
|
|
191
|
-
setup()
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
func willTerminate() {
|
|
195
|
-
suspend()
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
func blueEvent(event: BlueEventType, data: Any?) {
|
|
199
|
-
if (event == .accessCredentialAdded) {
|
|
200
|
-
schedule()
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
func setup() {
|
|
205
|
-
#if os(iOS)
|
|
206
|
-
backgroundScheduler.registerIdentifiers()
|
|
207
|
-
#endif
|
|
208
|
-
|
|
209
|
-
schedule(true)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
func schedule(_ now: Bool? = false) {
|
|
213
|
-
do {
|
|
214
|
-
guard try blueAccessCredentialsKeyChain.getNumberOfEntries() > 0 else {
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
} catch {
|
|
218
|
-
blueLogError(error.localizedDescription)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
blueRemoveEventListener(listener: self)
|
|
222
|
-
|
|
223
|
-
foregroundScheduler.schedule(now)
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
func suspend() {
|
|
227
|
-
foregroundScheduler.suspend()
|
|
228
|
-
|
|
229
|
-
#if os(iOS) || os(watchOS)
|
|
230
|
-
backgroundScheduler.suspend()
|
|
231
|
-
#endif
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
@available(macOS 10.15, *)
|
|
235
|
-
func syncTokens() async throws -> Void {
|
|
236
|
-
blueFireListeners(fireEvent: BlueEventType.tokenSyncStarted, data: nil)
|
|
237
|
-
|
|
238
|
-
defer {
|
|
239
|
-
blueFireListeners(fireEvent: BlueEventType.tokenSyncFinished, data: nil)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
let accessCredentialList = try await blueCommands.getAccessCredentials.runAsync()
|
|
243
|
-
|
|
244
|
-
await withThrowingTaskGroup(of: Void.self) { group in
|
|
245
|
-
// After deleting the app, since we store credentials in KeyChain Access, they reappear upon app reinstallation.
|
|
246
|
-
// But, as the device list is not saved there, it is lost.
|
|
247
|
-
// So, when searching for nearby devices, nothing is shown due to the absence of the device list.
|
|
248
|
-
// Although this issue would be solved in this synchronization, the synchronization may not return the device list as it depends on the refresh rate and can take up to 30 days, which is not ideal.
|
|
249
|
-
// Therefore, we force a refresh in case the app has never been launched before.
|
|
250
|
-
let forceRefresh = !blueAppHasLaunchedBefore()
|
|
251
|
-
|
|
252
|
-
for credential in accessCredentialList.credentials {
|
|
253
|
-
group.addTask {
|
|
254
|
-
do {
|
|
255
|
-
try await self.command.runAsync(credentialID: credential.credentialID.id, forceRefresh: forceRefresh)
|
|
256
|
-
|
|
257
|
-
blueLogDebug("Access credential has been successfully synchronized: \(credential.credentialID.id)")
|
|
258
|
-
} catch {
|
|
259
|
-
blueLogError("Access credential could not be synchronized: \(credential.credentialID.id) - \(error.localizedDescription)")
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|