@blueid/access-capacitor 0.77.0 → 0.78.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.
@@ -10,15 +10,16 @@
10
10
  <key>HeadersPath</key>
11
11
  <string>Headers</string>
12
12
  <key>LibraryIdentifier</key>
13
- <string>ios-arm64</string>
13
+ <string>macos-arm64_x86_64</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
- <string>ios</string>
22
+ <string>macos</string>
22
23
  </dict>
23
24
  <dict>
24
25
  <key>BinaryPath</key>
@@ -26,7 +27,7 @@
26
27
  <key>HeadersPath</key>
27
28
  <string>Headers</string>
28
29
  <key>LibraryIdentifier</key>
29
- <string>macos-arm64_x86_64</string>
30
+ <string>ios-arm64_x86_64-simulator</string>
30
31
  <key>LibraryPath</key>
31
32
  <string>libCBlueIDAccess.a</string>
32
33
  <key>SupportedArchitectures</key>
@@ -35,7 +36,9 @@
35
36
  <string>x86_64</string>
36
37
  </array>
37
38
  <key>SupportedPlatform</key>
38
- <string>macos</string>
39
+ <string>ios</string>
40
+ <key>SupportedPlatformVariant</key>
41
+ <string>simulator</string>
39
42
  </dict>
40
43
  <dict>
41
44
  <key>BinaryPath</key>
@@ -43,18 +46,15 @@
43
46
  <key>HeadersPath</key>
44
47
  <string>Headers</string>
45
48
  <key>LibraryIdentifier</key>
46
- <string>ios-arm64_x86_64-simulator</string>
49
+ <string>ios-arm64</string>
47
50
  <key>LibraryPath</key>
48
51
  <string>libCBlueIDAccess.a</string>
49
52
  <key>SupportedArchitectures</key>
50
53
  <array>
51
54
  <string>arm64</string>
52
- <string>x86_64</string>
53
55
  </array>
54
56
  <key>SupportedPlatform</key>
55
57
  <string>ios</string>
56
- <key>SupportedPlatformVariant</key>
57
- <string>simulator</string>
58
58
  </dict>
59
59
  </array>
60
60
  <key>CFBundlePackageType</key>
@@ -249,15 +249,18 @@ public class BlueUpdateDeviceConfigurationCommand: BlueAPIAsyncCommand {
249
249
  private func pushEventLogs(status: BlueSystemStatus, credential: BlueAccessCredential, deviceID: String, with tokenAuthentication: BlueTokenAuthentication) async throws {
250
250
  do {
251
251
  guard status.settings.eventLogEntriesCount > 0 else {
252
- blueLogWarn("No event logs to be deployed")
252
+ blueLogInfo("No event logs to be deployed")
253
253
  return
254
254
  }
255
255
 
256
- let limit = 40
257
-
258
- let pushEvents = { (_ offset: Int) in
256
+ try await iterateEvents(
257
+ sequenceID: status.settings.eventLogSequenceID,
258
+ entriesCount: status.settings.eventLogEntriesCount,
259
+ limit: 100
260
+ ) { offset in
261
+
259
262
  var query = BlueEventLogQuery()
260
- query.maxCount = UInt32(limit)
263
+ query.maxCount = UInt32(40)
261
264
 
262
265
  // newest -> oldest
263
266
  query.sequenceID = UInt32(offset)
@@ -279,20 +282,9 @@ public class BlueUpdateDeviceConfigurationCommand: BlueAPIAsyncCommand {
279
282
  }
280
283
  }
281
284
 
282
- return logResult
285
+ return logResult.events.count
283
286
  }
284
287
 
285
- var sent = 0
286
- var offset = max(1, Int(status.settings.eventLogSequenceID) - 100)
287
-
288
- repeat {
289
- let logResult = try await pushEvents(offset)
290
-
291
- offset += logResult.events.count
292
- sent += logResult.events.count
293
-
294
- } while (sent < 100 && offset < status.settings.eventLogEntriesCount)
295
-
296
288
  } catch {
297
289
  throw BlueError(.sdkEventLogsPushFailed, cause: error)
298
290
  }
@@ -301,11 +293,19 @@ public class BlueUpdateDeviceConfigurationCommand: BlueAPIAsyncCommand {
301
293
  @available(macOS 10.15, *)
302
294
  private func pushSystemLogs(status: BlueSystemStatus, deviceID: String, with tokenAuthentication: BlueTokenAuthentication) async throws {
303
295
  do {
304
- let limit = 10
296
+ guard status.settings.systemLogEntriesCount > 0 else {
297
+ blueLogInfo("No system log entries to be deployed")
298
+ return
299
+ }
305
300
 
306
- let pushEvents = { (_ offset: Int) in
301
+ try await iterateEvents(
302
+ sequenceID: status.settings.systemLogSequenceID,
303
+ entriesCount: status.settings.systemLogEntriesCount,
304
+ limit: 50
305
+ ) { offset in
306
+
307
307
  var query = BlueSystemLogQuery()
308
- query.maxCount = UInt32(limit)
308
+ query.maxCount = UInt32(10)
309
309
 
310
310
  // newest -> oldest
311
311
  query.sequenceID = UInt32(max(1, Int(status.settings.systemLogSequenceID) - offset + 1))
@@ -327,27 +327,26 @@ public class BlueUpdateDeviceConfigurationCommand: BlueAPIAsyncCommand {
327
327
  }
328
328
  }
329
329
 
330
- return logResult
330
+ return logResult.entries.count
331
331
  }
332
-
333
- var sent = 0
334
- var offset = 0
335
-
336
- repeat {
337
- offset += limit
338
-
339
- let logResult = try await pushEvents(offset)
340
- if (logResult.entries.count < limit) {
341
- break
342
- }
343
-
344
- sent += logResult.entries.count
345
-
346
- } while (sent < 50 && sent < status.settings.systemLogEntriesCount)
332
+
347
333
  } catch {
348
334
  throw BlueError(.sdkSystemLogEntriesPushFailed, cause: error)
349
335
  }
350
336
  }
337
+
338
+ private func iterateEvents(sequenceID: UInt32, entriesCount: UInt32, limit: Int, _ sendBatch: (_ offset: Int) async throws -> Int) async throws {
339
+ var sent = 0
340
+ var offset = max(1, Int(sequenceID) - limit)
341
+
342
+ repeat {
343
+ let entriesSent = try await sendBatch(offset)
344
+
345
+ offset += entriesSent
346
+ sent += entriesSent
347
+
348
+ } while (sent < limit && offset < entriesCount)
349
+ }
351
350
  }
352
351
 
353
352
  public class BlueGetAccessObjectsCommand: BlueAPIAsyncCommand {
@@ -537,12 +536,7 @@ public struct BlueTryAccessDeviceCommand: BlueAsyncCommand {
537
536
  }
538
537
 
539
538
  #if os(iOS) || os(watchOS)
540
- return try await blueShowAccessDeviceModal(
541
- title: blueI18n.openViaOssTitle,
542
- message: blueI18n.openViaOssWaitMessage,
543
- successfulMessage: blueI18n.openViaOssSuccessfulMessage,
544
- unsuccessfulMessage: blueI18n.openViaOssUnsuccessfulMessage
545
- ) {
539
+ return try await blueShowAccessDeviceModal {
546
540
  return try await tryOssAccess()
547
541
  }
548
542
  #else
@@ -2,41 +2,55 @@
2
2
  import Foundation
3
3
 
4
4
  /// Displays a modal view (sheet) which performs a scoped task related to accessing an device via OSS.
5
- /// - parameter title: The modal title.
6
- /// - parameter message: The modal message.
7
- /// - parameter successfulMessage: A successful message to be shown in case the OSS task grants access successfully.
8
- /// - parameter unsuccessfulMessage: An unsuccessful message to be shown in case the OSS task does not grant access successfully.
9
5
  /// - parameter task: The OSS task to be performed.
10
- public func blueShowAccessDeviceModal(
11
- title: String,
12
- message: String? = nil,
13
- successfulMessage: String? = nil,
14
- unsuccessfulMessage: String? = nil,
15
- _ task: @escaping () async throws -> BlueOssAccessResult)
16
- async throws -> BlueOssAccessResult {
6
+ public func blueShowAccessDeviceModal(_ task: @escaping () async throws -> BlueOssAccessResult) async throws -> BlueOssAccessResult {
17
7
  let session = BlueModalSession()
18
8
 
19
9
  blueRunInMainThread {
20
- session.begin(title: title, message: message)
10
+ session.begin(title: blueI18n.openViaOssTitle, message: blueI18n.openViaOssWaitMessage)
21
11
  }
22
12
 
23
13
  do {
24
14
  let result = try await task()
25
15
 
26
- if (!result.accessGranted) {
27
- blueRunInMainThread {
28
- session.invalidate(errorMessage: unsuccessfulMessage ?? "")
29
- }
30
- } else {
31
- blueRunInMainThread {
32
- session.invalidate(successMessage: successfulMessage ?? "")
16
+ blueRunInMainThread {
17
+ if (!result.accessGranted) {
18
+ if (result.hasScheduleMissmatch && result.scheduleMissmatch) {
19
+ session.invalidate(
20
+ title: blueI18n.openViaOssAccessDeniedTitle,
21
+ errorMessage: blueI18n.openViaOssAccessDeniedScheduleMismatchMessage
22
+ )
23
+ }
24
+ else {
25
+ session.invalidate(
26
+ title: blueI18n.openViaOssAccessDeniedTitle,
27
+ errorMessage: blueI18n.openViaOssAccessDeniedMessage
28
+ )
29
+ }
30
+ } else {
31
+ session.invalidate(
32
+ title: blueI18n.openViaOssAccessGrantedTitle,
33
+ successMessage: blueI18n.openViaOssAccessGrantedMessage
34
+ )
33
35
  }
34
36
  }
35
37
 
36
38
  return result
37
39
  } catch {
40
+ var errorMessage = error.localizedDescription
41
+
42
+ if let blueError = error as? BlueError {
43
+ errorMessage = "Error: \(String(describing: blueError.returnCode)). Code: \(blueError.returnCode.rawValue)"
44
+ }
45
+ else if let terminalError = error as? BlueTerminalError {
46
+ errorMessage = "Error: \(String(describing: terminalError.terminalError.returnCode)). Code: \(terminalError.terminalError.returnCode.rawValue)"
47
+ }
48
+
38
49
  blueRunInMainThread {
39
- session.invalidate(errorMessage: error.localizedDescription)
50
+ session.invalidate(
51
+ title: blueI18n.openViaOssErrorTitle,
52
+ errorMessage: errorMessage
53
+ )
40
54
  }
41
55
 
42
56
  throw error
@@ -36,9 +36,14 @@ internal class BlueModalSession {
36
36
  }
37
37
 
38
38
  /// Closes the modal session. The session cannot be re-used.
39
+ /// - parameter title: Optional title.
39
40
  /// - parameter errorMessage: The specified error message and an error symbol will be displayed momentarily on the modal before it is automatically dismissed.
40
41
  /// - parameter successMessage: The specified success message and an success symbol will be displayed momentarily on the modal before it is automatically dismissed.
41
- func invalidate(errorMessage: String? = nil, successMessage: String? = nil) {
42
+ func invalidate(
43
+ title: String? = nil,
44
+ errorMessage: String? = nil,
45
+ successMessage: String? = nil
46
+ ) {
42
47
  if (isInvalidated) {
43
48
  return
44
49
  }
@@ -50,16 +55,16 @@ internal class BlueModalSession {
50
55
  viewModel.showDismissButton = false
51
56
 
52
57
  if let errorMessage = errorMessage {
53
- viewModel.title = ""
58
+ viewModel.title = title ?? ""
54
59
  viewModel.message = errorMessage
55
60
  viewModel.status = .Failed
56
- delay = 2
61
+ delay = 3
57
62
 
58
63
  BlueSound.shared.play(BlueNegativeSoundSystemID)
59
64
  }
60
65
 
61
66
  if let successMessage = successMessage {
62
- viewModel.title = ""
67
+ viewModel.title = title ?? ""
63
68
  viewModel.message = successMessage
64
69
  viewModel.status = .Success
65
70
  delay = 2
@@ -119,6 +119,7 @@ internal struct BlueModalView: View {
119
119
  }
120
120
 
121
121
  Text(vm.message)
122
+ .multilineTextAlignment(.center)
122
123
  .font(.system(size: 12))
123
124
  .padding(.top, 20)
124
125
  .hidden(vm.message.isEmpty)
@@ -167,21 +168,23 @@ struct ContentView_Preview: PreviewProvider {
167
168
  static var previews: some View {
168
169
  BlueModalView(
169
170
  BlueModalViewModel(
170
- title: "Unlocking the device...",
171
- message: "Please wait..."
171
+ title: "Unlocking in Progress",
172
+ message: "Establishing secure connection..."
172
173
  )
173
174
  ) {}
174
175
 
175
176
  BlueModalView(
176
177
  BlueModalViewModel(
177
- message: "Success",
178
+ title: "Access Granted",
179
+ message: "Please proceed.",
178
180
  status: .Success
179
181
  )
180
182
  ) {}
181
183
 
182
184
  BlueModalView(
183
185
  BlueModalViewModel(
184
- message: "Failed",
186
+ title: "Access Denied",
187
+ message: "Credentials are not valid at this time and/or day of the week.",
185
188
  status: .Failed
186
189
  )
187
190
  ) {}
@@ -46,7 +46,7 @@ private final class BlueNfcSessionListener: NSObject, NFCTagReaderSessionDelegat
46
46
  }
47
47
  }
48
48
 
49
- internal func blueNfcExecute(_ handler: @escaping (_: BlueTransponderType) throws -> String, timeoutSeconds: Double = 0, ignoreErrors: [BlueReturnCode]? = nil) throws {
49
+ internal func blueNfcExecute(_ handler: @escaping (_: BlueTransponderType) throws -> String, timeoutSeconds: Double = 0, errorHandler: ((_: Error) -> String?)? = nil) throws {
50
50
  try blueExecuteWithTimeout({
51
51
  let isActive = blueNfcSession != nil
52
52
 
@@ -97,15 +97,17 @@ internal func blueNfcExecute(_ handler: @escaping (_: BlueTransponderType) throw
97
97
  } catch let error {
98
98
  var errorMessage: String? = BlueError.unknownErrorMessage
99
99
 
100
- if (error.localizedDescription != "") {
100
+ if let blueError = error as? BlueError {
101
+ errorMessage = "Error: \(String(describing: blueError.returnCode)). Code: \(blueError.returnCode.rawValue)"
102
+ }
103
+ else if (error.localizedDescription != "") {
101
104
  errorMessage = error.localizedDescription
102
105
  }
103
106
 
104
- if let ignoreErrors = ignoreErrors {
105
- if let blueError = error as? BlueError {
106
- if (ignoreErrors.contains(blueError.returnCode)) {
107
- errorMessage = nil
108
- }
107
+ if let errorHandler = errorHandler {
108
+ if let message = errorHandler(error) {
109
+ errorMessage = nil
110
+ blueNfcSession?.alertMessage = message
109
111
  }
110
112
  }
111
113
 
@@ -184,7 +186,7 @@ internal func blueNfc_Transceive(_ pCommandApdu: UnsafePointer<UInt8>, _ command
184
186
 
185
187
  #else
186
188
 
187
- internal func blueNfcExecute(_ handler: @escaping (_: BlueTransponderType) throws -> String, timeoutSeconds: Double = 0, ignoreErrors: [BlueReturnCode]? = nil) throws {
189
+ internal func blueNfcExecute(_ handler: @escaping (_: BlueTransponderType) throws -> String, timeoutSeconds: Double = 0, errorHandler: ((_: Error) -> String?)? = nil) throws {
188
190
  throw BlueError(.notSupported)
189
191
  }
190
192
 
@@ -80,11 +80,12 @@ public struct BlueOssSoCreateMobileCommand: BlueCommand {
80
80
  }
81
81
  }
82
82
 
83
+
83
84
  fileprivate func executeOssSoNfc<ResultType>(
84
85
  settings: BlueOssSoSettings?,
85
86
  successMessage: String,
86
- ignoreErrors: [BlueReturnCode]? = nil,
87
- handler: @escaping (_: UnsafeMutablePointer<BlueOssSoStorage_t>) throws -> ResultType) throws -> ResultType {
87
+ handler: @escaping (_: UnsafeMutablePointer<BlueOssSoStorage_t>) throws -> ResultType,
88
+ errorHandler: ((_: Error) -> String?)? = nil) throws -> ResultType {
88
89
 
89
90
  var result: ResultType? = nil
90
91
 
@@ -105,8 +106,8 @@ fileprivate func executeOssSoNfc<ResultType>(
105
106
  result = try handler(pStorage)
106
107
 
107
108
  return successMessage
108
- },
109
- ignoreErrors: ignoreErrors
109
+ },
110
+ errorHandler: errorHandler
110
111
  )
111
112
 
112
113
  guard let result = result else {
@@ -260,12 +261,12 @@ public struct BlueOssSoReadConfigurationCommand: BlueCommand {
260
261
  ))
261
262
  }
262
263
 
263
- public func run(_ settings: BlueOssSoSettings?, ignoreErrors: [BlueReturnCode]? = nil) throws -> BlueOssSoConfiguration {
264
- return try executeOssSoNfc(settings: settings, successMessage: blueI18n.nfcOssSuccessReadConfigurationMessage, ignoreErrors: ignoreErrors, handler: { pStorage in
264
+ public func run(_ settings: BlueOssSoSettings?, errorHandler: ((_: Error) -> String?)? = nil) throws -> BlueOssSoConfiguration {
265
+ return try executeOssSoNfc(settings: settings, successMessage: blueI18n.nfcOssSuccessReadConfigurationMessage, handler: { pStorage in
265
266
  return try blueClibFunctionOut({ (dataPtr, dataSize) in
266
267
  return blueOssSo_ReadConfiguration_Ext(pStorage, dataPtr, dataSize, BlueOssSoReadWriteFlags_t(rawValue: BlueOssSoReadWriteFlags_All.rawValue))
267
268
  })
268
- })
269
+ }, errorHandler: errorHandler)
269
270
  }
270
271
  }
271
272
 
@@ -323,9 +324,15 @@ public struct BlueReadOssSoCredentialCommand: BlueCommand {
323
324
 
324
325
  let ossSoSettings = try blueGetOssSoSettings(credentialID: credential.credentialID.id)
325
326
 
326
- return try BlueOssSoReadConfigurationCommand().run(ossSoSettings, ignoreErrors: [
327
- .notFound
328
- ])
327
+ return try BlueOssSoReadConfigurationCommand().run(ossSoSettings) { error in
328
+ if let blueError = error as? BlueError {
329
+ if (blueError.returnCode == .notFound) {
330
+ return blueI18n.nfcInitializingWritingProcess
331
+ }
332
+ }
333
+
334
+ return nil
335
+ }
329
336
  }
330
337
  }
331
338