Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Smart Selfie Capture #267

Merged
merged 39 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2a54e95
New Smart Selfie Capture UI (#202)
tobitech Jul 30, 2024
12e032e
Merge branch 'main' into new-smart-selfie-capture
tobitech Jul 31, 2024
0a24fa1
Merge branch 'main' into new-smart-selfie-capture
tobitech Aug 7, 2024
1c3293a
Merge branch 'main' into new-smart-selfie-capture
tobitech Aug 19, 2024
a758481
Merge branch 'main' into new-smart-selfie-capture
tobitech Aug 19, 2024
877bbb2
Merge branch 'main' into new-smart-selfie-capture
tobitech Aug 19, 2024
f6b9b83
Selfie Quality Check With CoreML Model (#206)
tobitech Aug 26, 2024
acd4b78
Merge branch 'main' into new-smart-selfie-capture
tobitech Aug 29, 2024
bc00398
run pod install
tobitech Sep 2, 2024
2ae0884
Introduce new versions for FaceDetector, SelfieViewModel classes and …
tobitech Sep 10, 2024
7ace3ea
Merge branch 'main' into new-smart-selfie-capture
tobitech Sep 10, 2024
ae9f30c
run pod install
tobitech Sep 10, 2024
16db3d6
Merge branch 'main' into new-smart-selfie-capture
tobitech Sep 18, 2024
801dbb6
run pod install.
tobitech Sep 18, 2024
7843341
Liveness Capture Instructions Screen (#229)
tobitech Sep 18, 2024
2bc0884
Merge branch 'main' into new-smart-selfie-capture
tobitech Sep 20, 2024
42c734c
run pod install.
tobitech Sep 20, 2024
5f1ab99
Merge branch 'main' into new-smart-selfie-capture
tobitech Sep 26, 2024
e26f608
run pod install
tobitech Sep 26, 2024
a4b7ffe
New Camera UI (#235)
tobitech Sep 26, 2024
58b3d3b
Merge branch 'main' into new-smart-selfie-capture
tobitech Oct 3, 2024
f0ac875
run pod install.
tobitech Oct 3, 2024
135f057
Connect ViewModel to New UI and Refactoring (#237)
tobitech Oct 9, 2024
4b62510
Merge branch 'main' into new-smart-selfie-capture
tobitech Oct 24, 2024
bdbf4a7
Merge branch 'main' into new-smart-selfie-capture
tobitech Oct 28, 2024
1c642f5
run pod install
tobitech Oct 28, 2024
a93950f
Box Oval Interface for Selfie Capture Screen (#250)
tobitech Nov 6, 2024
87f434f
Face Validator Tests (#252)
tobitech Nov 8, 2024
9951083
Merge branch 'main' into new-smart-selfie-capture
tobitech Nov 11, 2024
569676f
run pod install
tobitech Nov 11, 2024
7a12c00
Merge branch 'main' into new-smart-selfie-capture
tobitech Dec 10, 2024
e7e1069
run pod install.
tobitech Dec 10, 2024
26a110f
Liveness Timeout Images (#253)
tobitech Dec 10, 2024
304fe7f
Fix UserID Refresh for New Jobs (#262)
tobitech Dec 11, 2024
8b7279e
Device Motion Orientation (#263)
tobitech Dec 12, 2024
819d2ff
Fix Selfie and Liveness Image Sizes, Fix Layout for Small Screen Devi…
tobitech Dec 13, 2024
9806243
Adding Active Liveness Metadata (#265)
jumaallan Dec 13, 2024
2f1268d
update changelog.
tobitech Dec 13, 2024
9f24319
Merge branch 'main' into new-smart-selfie-capture
jumaallan Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

* Fixed missing idType on Document Verification Jobs
* Introduce screens for the new Enhanced Selfie Capture Enrollment and Authentication Products.

## 10.2.17

Expand Down
2 changes: 1 addition & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ SPEC CHECKSUMS:
lottie-ios: fcb5e73e17ba4c983140b7d21095c834b3087418
netfox: 9d5cc727fe7576c4c7688a2504618a156b7d44b7
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
SmileID: 44fef36001a02aa7362368e8a3f1127c03751166
SmileID: dc04628f6e1572fc6e407649bfd05f91647ed947
SwiftLint: 3fe909719babe5537c552ee8181c0031392be933
ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c

Expand Down
146 changes: 75 additions & 71 deletions Example/SmileID.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

40 changes: 21 additions & 19 deletions Example/SmileID/BiometricKYC/BiometricKycWithIdInputScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct BiometricKycWithIdInputScreen: View {
let delegate: BiometricKycResultDelegate

@State private var selectedCountry: CountryInfo?
@ObservedObject var viewModel: BiometricKycWithIdInputScreenViewModel
@StateObject var viewModel: BiometricKycWithIdInputScreenViewModel

var body: some View {
switch viewModel.step {
Expand All @@ -19,25 +19,27 @@ struct BiometricKycWithIdInputScreen: View {
}
.frame(maxWidth: .infinity)
case .idTypeSelection(let countryList):
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
VStack {
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
)
}
}
case .consent(let country, let idType, let requiredFields):
SmileID.consentScreen(
Expand Down
38 changes: 20 additions & 18 deletions Example/SmileID/EnhancedKYC/EnhancedKycWithIdInputScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,27 @@ struct EnhancedKycWithIdInputScreen: View {
}
.frame(maxWidth: .infinity)
case .idTypeSelection(let countryList):
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
VStack {
SearchableDropdownSelector(
items: countryList,
selectedItem: selectedCountry,
itemDisplayName: { $0.name },
onItemSelected: { selectedCountry = $0 }
)
if let selectedCountry = selectedCountry {
RadioGroupSelector(
title: "Select ID Type",
items: selectedCountry.availableIdTypes,
itemDisplayName: { $0.label },
onItemSelected: { idType in
viewModel.onIdTypeSelected(
country: selectedCountry.countryCode,
idType: idType.idTypeKey,
requiredFields: idType.requiredFields ?? []
)
}
)
}
}
case .consent(let country, let idType, let requiredFields):
SmileID.consentScreen(
Expand Down
71 changes: 53 additions & 18 deletions Example/SmileID/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ struct HomeView: View {
@StateObject var viewModel: HomeViewModel

init(config: Config) {
_viewModel = StateObject(wrappedValue: HomeViewModel(config: config))
_viewModel = StateObject(wrappedValue: HomeViewModel(config: config))
}

let columns = [GridItem(.flexible()), GridItem(.flexible())]

var body: some View {
NavigationView {
VStack(spacing: 24) {
Text("Test Our Products")
.font(SmileID.theme.header2)
.foregroundColor(.black)

MyVerticalGrid(
maxColumns: 2,
items: [
ScrollView(showsIndicators: false) {
LazyVGrid(columns: columns) {
ProductCell(
image: "smart_selfie_enroll",
name: "SmartSelfie™ Enrollment",
Expand All @@ -28,17 +28,17 @@ struct HomeView: View {
},
content: {
SmileID.smartSelfieEnrollmentScreen(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
jobId: viewModel.newJobId,
allowAgentMode: true,
delegate: SmartSelfieEnrollmentDelegate(
userId: viewModel.smartSelfieEnrollmentUserId,
userId: viewModel.newUserId,
onEnrollmentSuccess: viewModel.onSmartSelfieEnrollment,
onError: viewModel.didError
)
)
}
),
)
ProductCell(
image: "smart_selfie_authentication",
name: "SmartSelfie™ Authentication",
Expand All @@ -47,11 +47,45 @@ struct HomeView: View {
},
content: {
SmartSelfieAuthWithUserIdEntry(
initialUserId: viewModel.smartSelfieEnrollmentUserId,
initialUserId: viewModel.lastSelfieEnrollmentUserId ?? "",
delegate: viewModel
)
}
)
ProductCell(
image: "smart_selfie_enroll",
name: "SmartSelfie™ Enrollment (Enhanced)",
onClick: {
viewModel.onProductClicked()
},
content: {
SmileID.smartSelfieEnrollmentScreen(
userId: viewModel.newUserId,
jobId: viewModel.newJobId,
allowAgentMode: true,
useStrictMode: true,
delegate: SmartSelfieEnrollmentDelegate(
userId: viewModel.newUserId,
onEnrollmentSuccess: viewModel.onSmartSelfieEnrollment,
onError: viewModel.didError
)
)
}
)
ProductCell(
image: "smart_selfie_authentication",
name: "SmartSelfie™ Authentication (Enhanced)",
onClick: {
viewModel.onProductClicked()
},
content: {
SmartSelfieAuthWithUserIdEntry(
initialUserId: viewModel.lastSelfieEnrollmentUserId ?? "",
useStrictMode: true,
delegate: viewModel
)
}
),
)
ProductCell(
image: "enhanced_kyc",
name: "Enhanced KYC",
Expand All @@ -67,7 +101,7 @@ struct HomeView: View {
)
)
}
),
)
ProductCell(
image: "biometric",
name: "Biometric KYC",
Expand All @@ -83,7 +117,7 @@ struct HomeView: View {
)
)
}
),
)
ProductCell(
image: "document",
name: "\nDocument Verification",
Expand All @@ -97,7 +131,7 @@ struct HomeView: View {
delegate: viewModel
)
}
),
)
ProductCell(
image: "enhanced_doc_v",
name: "Enhanced Document Verification",
Expand All @@ -112,10 +146,8 @@ struct HomeView: View {
)
}
)
].map {
AnyView($0)
}
)
}

Text("Partner \(viewModel.partnerId) - Version \(version) - Build \(build)")
.font(SmileID.theme.body)
Expand Down Expand Up @@ -164,14 +196,17 @@ struct SmartSelfieEnrollmentDelegate: SmartSelfieResultDelegate {

private struct SmartSelfieAuthWithUserIdEntry: View {
let initialUserId: String
var useStrictMode: Bool = false
let delegate: SmartSelfieResultDelegate

@State private var userId: String?

var body: some View {
if let userId {
SmileID.smartSelfieAuthenticationScreen(
userId: userId,
allowAgentMode: true,
useStrictMode: useStrictMode,
delegate: delegate
)
} else {
Expand Down Expand Up @@ -262,9 +297,9 @@ private struct MyVerticalGrid: View {
ScrollView {
VStack(alignment: .leading, spacing: 8) {
let numRows = (items.count + maxColumns - 1) / maxColumns
ForEach(0 ..< numRows) { rowIndex in
ForEach(0 ..< numRows, id: \.self) { rowIndex in
HStack(spacing: 16) {
ForEach(0 ..< maxColumns) { columnIndex in
ForEach(0 ..< maxColumns, id: \.self) { columnIndex in
let itemIndex = rowIndex * maxColumns + columnIndex
let width = geo.size.width / CGFloat(maxColumns)
if itemIndex < items.count {
Expand Down
5 changes: 4 additions & 1 deletion Example/SmileID/Home/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ class HomeViewModel: ObservableObject,
@Published var partnerId: String
var networkMonitor = NetworkMonitor.shared

@Published private(set) var smartSelfieEnrollmentUserId = generateUserId()
var lastSelfieEnrollmentUserId: String? {
guard let value = UIPasteboard.general.string else { return nil }
return value.hasPrefix("user-") ? value : nil
}
@Published private(set) var newUserId: String = generateUserId()
@Published private(set) var newJobId: String = generateJobId()

Expand Down
26 changes: 21 additions & 5 deletions Example/SmileID/Home/ProductCell.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import SmileID
import SwiftUI

struct ProductCell: View {
struct ProductCell<Content: View>: View {
let image: String
let name: String
let onClick: (() -> Void)?
@ViewBuilder let content: () -> any View
@ViewBuilder let content: () -> Content
@State private var isPresented: Bool = false

init(
image: String,
name: String,
onClick: (() -> Void)? = nil,
@ViewBuilder content: @escaping () -> any View
@ViewBuilder content: @escaping () -> Content
) {
self.image = image
self.name = name
Expand Down Expand Up @@ -41,8 +41,24 @@ struct ProductCell: View {
.frame(maxWidth: .infinity)
.background(SmileID.theme.accent)
.cornerRadius(8)
.sheet(isPresented: $isPresented, content: { AnyView(content())
})
.fullScreenCover(
isPresented: $isPresented,
content: {
NavigationView {
content()
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button {
isPresented = false
} label: {
Text(SmileIDResourcesHelper.localizedString(for: "Action.Cancel"))
.foregroundColor(SmileID.theme.accent)
}
}
}
}
}
)
}
)
}
Expand Down
2 changes: 2 additions & 0 deletions Example/SmileID/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
Expand Down
2 changes: 1 addition & 1 deletion Example/SmileID/WelcomeScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct WelcomeScreen: View {
.padding(.vertical)

Text("To begin testing, you need to add a configuration from the Smile Portal")
.font(EpilogueFont.regular(with: 16))
.font(DMSansFont.regular(with: 16))
.foregroundColor(SmileID.theme.onLight)
.padding(.vertical)

Expand Down
Loading
Loading