Skip to content

Commit b05510a

Browse files
committed
Merge branch 'main' into release
* main: chore: update user agent string with correct library version (#42) fix: update no match timeout check from frame count to elapsed time (#41) fix: send client close frame (#39) fix: data race causing multiple initial events and crash with low net… (#40) chore: remove countdown from liveness session check (#36)
2 parents 5b47401 + adf29ad commit b05510a

10 files changed

+65
-238
lines changed

Sources/FaceLiveness/Utilities/LocalizedStringKey+Liveness.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,6 @@ extension LocalizedStringKey {
8383
"amplify_ui_liveness_challenge_recording_indicator_label"
8484
)
8585

86-
/// en = "Hold face position during countdown."
87-
static let challenge_instruction_hold_face_during_countdown = LocalizedStringKey(
88-
"amplify_ui_liveness_challenge_instruction_hold_face_during_countdown"
89-
)
90-
9186
/// en = "Hold face in oval for colored lights."
9287
static let challenge_instruction_hold_face_during_freshness = LocalizedStringKey(
9388
"amplify_ui_liveness_challenge_instruction_hold_face_during_freshness"

Sources/FaceLiveness/Utilities/UserAgent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct UserAgentValues {
5757
swiftVersion: Swift().version(),
5858
unameMachine: Device.current.machine.replacingOccurrences(of: ",", with: "_"),
5959
locale: Locale.current.identifier,
60-
lib: "lib/amplify-ui-swift-face-liveness/1.0.1",
60+
lib: "lib/amplify-ui-swift-face-liveness/1.1.0",
6161
additionalMetadata: additionalMetadata
6262
)
6363
}

Sources/FaceLiveness/Views/Countdown/CountdownInstructionContainerView.swift

Lines changed: 0 additions & 52 deletions
This file was deleted.

Sources/FaceLiveness/Views/Countdown/CountdownView+ViewModel.swift

Lines changed: 0 additions & 67 deletions
This file was deleted.

Sources/FaceLiveness/Views/Countdown/CountdownView.swift

Lines changed: 0 additions & 64 deletions
This file was deleted.

Sources/FaceLiveness/Views/Instruction/InstructionContainerView.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,26 @@ struct InstructionContainerView: View {
9191
percentage: 0.2
9292
)
9393
.frame(width: 200, height: 30)
94+
case .pendingFacePreparedConfirmation(let reason):
95+
InstructionView(
96+
text: .init(reason.rawValue),
97+
backgroundColor: .livenessBackground
98+
)
99+
case .completedDisplayingFreshness:
100+
InstructionView(
101+
text: .challenge_verifying,
102+
backgroundColor: .livenessBackground
103+
)
104+
.onAppear {
105+
UIAccessibility.post(
106+
notification: .announcement,
107+
argument: NSLocalizedString(
108+
"amplify_ui_liveness_challenge_verifying",
109+
bundle: .module,
110+
comment: ""
111+
)
112+
)
113+
}
94114
default:
95115
EmptyView()
96116
}

Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel+FaceDetectionResultHandler.swift

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import SwiftUI
1010
@_spi(PredictionsFaceLiveness) import AWSPredictionsPlugin
1111

1212
fileprivate let initialFaceDistanceThreshold: CGFloat = 0.32
13-
fileprivate let countdownFaceDistanceThreshold: CGFloat = 0.37
1413

1514
extension FaceLivenessDetectionViewModel: FaceDetectionResultHandler {
1615
func process(newResult: FaceDetectionResult) {
@@ -34,25 +33,20 @@ extension FaceLivenessDetectionViewModel: FaceDetectionResultHandler {
3433
switch livenessState.state {
3534
case .pendingFacePreparedConfirmation:
3635
if face.faceDistance <= initialFaceDistanceThreshold {
37-
DispatchQueue.main.async {
38-
self.livenessState.startCountdown()
39-
self.initializeLivenessStream()
40-
}
36+
DispatchQueue.main.async {
37+
self.livenessState.awaitingRecording()
38+
self.initializeLivenessStream()
39+
}
40+
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
41+
self.livenessState.beginRecording()
42+
}
4143
return
4244
} else {
4345
DispatchQueue.main.async {
4446
self.livenessState.faceNotPrepared(reason: .faceTooClose)
4547
}
4648
return
4749
}
48-
case .countingDown:
49-
if face.faceDistance >= countdownFaceDistanceThreshold {
50-
DispatchQueue.main.async {
51-
self.livenessState.unrecoverableStateEncountered(
52-
.invalidFaceMovementDuringCountdown
53-
)
54-
}
55-
}
5650
case .recording(ovalDisplayed: false):
5751
drawOval(onComplete: {
5852
self.sendInitialFaceDetectedEvent(

Sources/FaceLiveness/Views/Liveness/LivenessStateMachine.swift

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,6 @@ struct LivenessStateMachine {
2525
state = .pendingFacePreparedConfirmation(reason)
2626
}
2727

28-
mutating func openSocket() {
29-
switch state {
30-
case .pendingFacePreparedConfirmation, .countingDown:
31-
state = .socketOpened
32-
default:
33-
break
34-
}
35-
}
36-
3728
mutating func awaitingFaceMatch(with instruction: Instructor.Instruction, nearnessPercentage: Double) {
3829
let reason: FaceNotPreparedReason
3930
let percentage: Double
@@ -56,16 +47,11 @@ struct LivenessStateMachine {
5647
state = .awaitingFaceInOvalMatch(reason, percentage)
5748
}
5849

59-
mutating func awaitingServerInfoEvent() {
60-
guard case .socketOpened = state else { return }
61-
state = .awaitingServerInfoEvent
62-
}
63-
64-
mutating func receivedServerInfoEvent() throws {
65-
guard case .awaitingServerInfoEvent = state else { return }
66-
state = .serverInfoEventReceived
50+
mutating func awaitingRecording() {
51+
guard case .pendingFacePreparedConfirmation = state else { return }
52+
state = .waitForRecording
6753
}
68-
54+
6955
mutating func unrecoverableStateEncountered(_ error: LivenessError) {
7056
switch state {
7157
case .encounteredUnrecoverableError, .completed:
@@ -83,11 +69,6 @@ struct LivenessStateMachine {
8369
state = .recording(ovalDisplayed: true)
8470
}
8571

86-
mutating func startCountdown() {
87-
guard case .pendingFacePreparedConfirmation = state else { return }
88-
state = .countingDown
89-
}
90-
9172
mutating func faceMatched() {
9273
state = .faceMatched
9374
}
@@ -106,7 +87,7 @@ struct LivenessStateMachine {
10687

10788
var shouldDisplayRecordingIcon: Bool {
10889
switch state {
109-
case .initial, .pendingFacePreparedConfirmation, .encounteredUnrecoverableError, .countingDown:
90+
case .initial, .pendingFacePreparedConfirmation, .encounteredUnrecoverableError:
11091
return false
11192
default: return true
11293
}
@@ -115,10 +96,6 @@ struct LivenessStateMachine {
11596
enum State: Equatable {
11697
case initial
11798
case pendingFacePreparedConfirmation(FaceNotPreparedReason)
118-
case socketOpened
119-
case awaitingServerInfoEvent
120-
case serverInfoEventReceived
121-
case countingDown
12299
case recording(ovalDisplayed: Bool)
123100
case awaitingFaceInOvalMatch(FaceNotPreparedReason, Double)
124101
case faceMatched
@@ -129,6 +106,7 @@ struct LivenessStateMachine {
129106
case awaitingDisconnectEvent
130107
case disconnectEventReceived
131108
case encounteredUnrecoverableError(LivenessError)
109+
case waitForRecording
132110
}
133111

134112
enum FaceNotPreparedReason: String, Equatable {

Sources/FaceLiveness/Views/Liveness/_FaceLivenessDetectionView.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@ struct _FaceLivenessDetectionView<VideoView: View>: View {
5050
)
5151

5252
Spacer()
53-
54-
CountdownInstructionContainerView(
55-
viewModel: viewModel,
56-
onCountdownComplete: {
57-
viewModel.livenessState.beginRecording()
58-
}
59-
)
60-
.padding(.bottom)
6153
}
6254
.padding([.leading, .trailing])
6355
.aspectRatio(3/4, contentMode: .fit)

0 commit comments

Comments
 (0)