Skip to content

Commit 22e5a07

Browse files
committed
implement pr comments
1 parent 1bea741 commit 22e5a07

File tree

3 files changed

+80
-34
lines changed

3 files changed

+80
-34
lines changed

docs/capability-guides/mobile-access/mobile-device-sdks/handling-system-permissions.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,40 @@
11
# Handling System Permissions
22

3-
Missing or required system permissions (Bluetooth, internet connectivity, etc.) are surfaced as `CredentialError.userInteractionRequired(action)` entries on each credential’s `errors` array. Observe these errors after activation and handle the specified actions. Errors are automatically updated to reflect current requirements.
3+
The mobile SDK surfaces missing or required system permissions (Bluetooth, internet connectivity, and so on) as `CredentialError.userInteractionRequired(action)` entries in each credential’s `errors` array. After activation, observe these errors and handle the specified actions. Errors update automatically as requirements change.
44

55
## Monitoring Permission Errors
66

77
{% tabs %}
8+
9+
{% tab title="Android Kotlin" %}
10+
```kotlin
11+
coroutineScope.launch {
12+
SeamSDK.getInstance().credentials.collect { credentialsList ->
13+
val errors = credentialsList.flatMap { it.errors }
14+
errors.forEach { error ->
15+
when (error) {
16+
is SeamCredentialError.Expired -> { /* handle credential expiration error */}
17+
is SeamCredentialError.Loading -> { /* handle not loaded yet */ }
18+
is SeamCredentialError.Unknown -> { /* handle unknown error */}
19+
is SeamCredentialError.UserInteractionRequired -> {
20+
handleUserInteractionRequired(error.interaction)
21+
}
22+
}
23+
}
24+
}
25+
}
26+
```
27+
{% endtab %}
28+
829
{% tab title="iOS Swift" %}
930

1031
Use Combine to watch the published credentials array and handle permission-related errors:
1132

1233

1334
```swift
35+
import SeamSDK
36+
import Combine
37+
1438
func startMonitoringPermissionErrors() {
1539
permissionCancellable = Seam.shared.$credentials
1640
.map { credentials in
@@ -31,13 +55,27 @@ func startMonitoringPermissionErrors() {
3155
{% endtabs %}
3256

3357

34-
The Seam SDK automatically clears resolved permission errors once the required permission is granted, reflecting the updated credential state.
58+
The mobile SDK automatically clears resolved permission errors once the required permission is granted, reflecting the updated credential state.
3559

3660
## Handling Permission Actions
3761

3862
Implement your handler for each action:
3963

4064
{% tabs %}
65+
66+
{% tab title="Android Kotlin" %}
67+
```kotlin
68+
fun handleUserInteractionRequired(interaction: SeamRequiredUserInteraction) {
69+
when (interaction) {
70+
is SeamRequiredUserInteraction.CompleteOtpAuthorization -> { /* handle OTP authorization */ }
71+
is SeamRequiredUserInteraction.EnableBluetooth -> { /* handle Bluetooth error */ }
72+
is SeamRequiredUserInteraction.EnableInternet -> { /* handle Internet connection error*/ }
73+
is SeamRequiredUserInteraction.GrantPermissions -> { /* handle permissions error*/ }
74+
}
75+
}
76+
```
77+
{% endtab %}
78+
4179
{% tab title="iOS Swift" %}
4280
```swift
4381
func handlePermissionAction(_ action: CredentialUserAction) {
@@ -57,4 +95,4 @@ func handlePermissionAction(_ action: CredentialUserAction) {
5795

5896
## See also
5997

60-
For a complete SwiftUI-based implementation of credential error handling for iOS, see the `SeamUnlockCardView` in the SeamComponents library, which demonstrates observing credential errors and updating the UI accordingly.
98+
For a complete SwiftUI-based implementation of credential error handling for iOS, see `SeamUnlockCardView` in the SeamComponents library, which demonstrates observing credential errors and updating the UI accordingly.

docs/capability-guides/mobile-access/mobile-device-sdks/initializing-the-seam-mobile-sdk.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737

3838
{% tab title="iOS Swift" %}
3939
You can install SeamSDK via CocoaPods or Swift Package Manager (SPM).
40-
SeamSDK supports per-lock-provider integration granularity--include only the modules you need to minimize your app's footprint.
40+
SeamSDK supports per-lock-provider integration granularity. Include only the modules you need to keep your app footprint minimal.
4141

4242
{% code title="Podfile" %}
4343
```ruby
@@ -206,12 +206,11 @@ $token = $client_session->token;
206206
## 4. Initialize the Mobile SDK with the Client Session Token
207207

208208

209-
Use the client session token you generated earlier to bootstrap the Seam SDK on the device. Under the hood, this will set up credential synchronization and start a background sync loop to keep credentials up to date.
210-
209+
Use the client session token that you generated earlier to bootstrap the Seam SDK on the device. Under the hood, this action sets up credential synchronization and starts a background sync loop to keep permissions up to date.
211210

212211
### Initialization and Error Handling
213212

214-
Perform initialization and activation within your app’s asynchronous context (e.g., Swift’s `Task` or Kotlin coroutines) so you can handle errors. The initialization call may fail due to configuration issues (such as an invalid token), and the activation call may fail due to network or runtime errors. Catch these errors and present a user-friendly message or fallback UI as appropriate.
213+
Perform initialization and activation within your app’s asynchronous context (for example, Swift’s `Task` or Kotlin coroutines) so that you can handle errors. The initialization call may fail due to configuration issues (such as an invalid token), and the activation call may fail due to network or runtime errors. Catch these errors and present a user-friendly message or fallback UI as appropriate.
215214

216215
{% tabs %}
217216
{% tab title="Android Kotlin" %}
@@ -243,16 +242,16 @@ try {
243242
```swift
244243
import SeamSDK
245244

246-
// Initialize the Mobile SDK with the Client Session Token (CST)
245+
// Initialize the Mobile SDK with the client session token (CST).
247246
Task {
248247
do {
249-
// Bootstrap the SDK with the CST from your login flow
248+
// Bootstrap the SDK with the CST from your login flow.
250249
try Seam.initialize(clientSessionToken: token)
251-
// Start credential sync and background polling
250+
// Start credential sync and background polling.
252251
try await Seam.shared.activate()
253-
print("Seam SDK is now active")
252+
print("Seam SDK is now active.")
254253
} catch let error as SeamError {
255-
// Handle SDK-specific initialization errors (invalid token, etc)
254+
// Handle SDK-specific initialization errors (invalid token, etc).
256255
showAlert(title: "Initialization Failed", message: error.localizedDescription)
257256
}
258257
}
@@ -263,7 +262,7 @@ Task {
263262

264263
### Credential Errors
265264

266-
Any errors that occur between activation and deactivation surface on individual credential objects via their `errors` property. Observe the `credentials` array to detect and handle these errors:
265+
Any errors that occur between activation and deactivation surface on individual credential objects through their `errors` property. Observe the `credentials` array to detect and handle these errors:
267266

268267
```swift
269268
import SeamSDK

docs/capability-guides/mobile-access/mobile-device-sdks/using-unlock-with-tap.md

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ description: >-
55

66
# Unlocking
77

8-
Unlocking with SeamSDK uses proximity to communicate credentials to door readers. When a user initiates an unlock, the SDK performs scanning, error handling, and unlock events via `Seam.shared.unlock(using:)`.
8+
Unlocking with SeamSDK uses proximity to communicate credentials to door readers. When a user initiates an unlock, the SDK performs scanning, error handling, and unlock events using `Seam.shared.unlock(using:)`.
99

1010
Using this process involves the following steps:
1111

1212
1. Retrieve available mobile credentials.
13-
2. Monitor for permission or credential errors unhandled errors will be thrown as `credentialErrors([SeamCredentialError])`
13+
2. Monitor for permission or credential errors. Unhandled errors are thrown as `credentialErrors([SeamCredentialError])`.
1414
3. Perform the unlock operation.
1515
4. Handle unlock status events.
1616
5. Cancel the unlock operation if needed.
@@ -19,18 +19,21 @@ Using this process involves the following steps:
1919

2020
## 1. Retrieve Mobile Credentials
2121

22-
Access the current credentials via the published `credentials` array on `Seam.shared`:
22+
Access the current credentials through the published `credentials` array on `Seam.shared`:
2323

2424
{% tabs %}
2525
{% tab title="iOS Swift" %}
2626
```swift
27+
import SeamSDK
28+
import Combine
29+
2730
// Access credentials
2831
let credentials = Seam.shared.credentials
2932

3033
// Observe updates with Combine
3134
let credentialsSubscription = Seam.shared.$credentials
3235
.sink { creds in
33-
// Update UI with new credentials array
36+
// Update UI with new credentials array.
3437
}
3538
```
3639
{% endtab %}
@@ -43,30 +46,36 @@ Permission or setup issues appear in each credential’s `errors` property. Obse
4346
{% tabs %}
4447
{% tab title="iOS Swift" %}
4548
```swift
49+
import SeamSDK
50+
import Combine
51+
4652
let errorSubscription = Seam.shared.$credentials
4753
.flatMap { creds in creds.publisher }
4854
.map { $0.errors }
4955
.sink { errors in
50-
// Handle errors, e.g. `.userInteractionRequired`, `.expired`, etc.
56+
// Handle errors, for example, `.userInteractionRequired`, `.expired`, etc.
5157
}
5258
```
5359
{% endtab %}
5460
{% endtabs %}
5561

56-
> **Note:** The `.errors` array on credentials represents per-credential issues though some issues may be repeated across several credentials (e.g. bluetooth requirements). Seam SDK- or credential-level errors (such as invalid token or expired credential) are thrown directly by `unlock(using:)` as `SeamError` and must be handled via `do/catch`.
62+
> **Note:** The `.errors` array on credentials represents per-credential issues, though some issues may be repeated across several credentials (for example, bluetooth requirements). SDK- or credential-level errors (such as invalid token or expired credential) are thrown directly by methods like `unlock(using:)` because `SeamError` or `SeamCredentialError` and must be handled through `do/catch`.
5763
5864
## 3. Perform Unlock Operation
5965

6066
The call to `Seam.shared.unlock(using:)` may throw:
61-
- `SeamError`: for SDK-level issues (e.g., invalid token, uninitialized SDK).
62-
- `SeamCredentialError`: for credential-specific issues (e.g., expired credential, device not eligible).
63-
Ensure you wrap the call in `do/catch` to handle these errors.
67+
- `SeamError`: For SDK-level issues (for example, invalid token, uninitialized SDK).
68+
- `SeamCredentialError`: For credential-specific issues (for example, expired credential, device not eligible).
69+
Ensure that you wrap the call in `do/catch` blocks to handle these errors.
6470

6571
Use Async/Await or Combine to initiate an unlock with a selected credential:
6672

6773
{% tabs %}
6874
{% tab title="iOS Swift" %}
6975
```swift
76+
import SeamSDK
77+
import Combine
78+
7079
let credentialId = credentials.first!.id
7180

7281
// Async/Await example
@@ -75,14 +84,14 @@ Task {
7584
for try await event in try Seam.shared.unlock(using: credentialId).values {
7685
switch event {
7786
case .grantedAccess:
78-
// The lock granted access—show a success indicator.
87+
// The lock granted access. Show a success indicator.
7988
default:
8089
print("Unlock event: \(event)")
81-
// Access wasn't granted, inform the user and offer retry.
90+
// Access wasn't granted. Inform the user and offer retry.
8291
}
8392
}
8493
} catch {
85-
// Handle unlock error, e.g., invalid credential or SDK error
94+
// Handle unlock error, for example, invalid credential or SDK error
8695
print("Unlock error: \(error)")
8796
}
8897
}
@@ -106,7 +115,7 @@ do {
106115
)
107116
// Retain `unlockSubscription`; discarding it will cancel the unlock attempt.
108117
} catch {
109-
// Handle unlock initialization error
118+
// Handle unlock initialization error.
110119
print("Unlock error: \(error)")
111120
}
112121
```
@@ -137,17 +146,17 @@ Task {
137146
for try await event in Seam.shared.unlock(using: credentialID) {
138147
switch event {
139148
case .launched:
140-
// Show scanning indicator
149+
// Show scanning indicator.
141150
case .grantedAccess:
142-
// Show access granted
151+
// Show access granted.
143152
case .timedOut:
144-
// Show timeout and offer retry
153+
// Show timeout and offer retry.
145154
case .connectionFailed(let debugDescription):
146-
// Show error with debugDescription
155+
// Show error with debugDescription.
147156
}
148157
}
149158
} catch {
150-
// Handle thrown errors
159+
// Handle thrown errors.
151160
}
152161
}
153162
```
@@ -176,9 +185,9 @@ do {
176185
}
177186
}
178187
)
179-
// Retain `unlockSubscription` as a property and cancel when appropriate (e.g., in deinit or viewWillDisappear).
188+
// Retain `unlockSubscription` as a property and cancel when appropriate (for example, in deinit or viewWillDisappear).
180189
} catch {
181-
// Handle unlock initialization error
190+
// Handle unlock initialization error.
182191
print("Unlock initialization error: \(error)")
183192
}
184193
```
@@ -195,7 +204,7 @@ Stop scanning by cancelling your subscription or task:
195204
// For Combine
196205
unlockSubscription.cancel()
197206

198-
// For Async/Await, cancel the Task as needed
207+
// For Async/Await, cancel the Task as needed.
199208
```
200209
{% endtab %}
201210
{% endtabs %}

0 commit comments

Comments
 (0)