Skip to content

Commit

Permalink
Offline Mode on iOS (#167)
Browse files Browse the repository at this point in the history
* Reworked Local Storage  (#147)

* reworked file creation logic

* added create info.json file

* made create file more abstract

* removed whitespace

* updated info.json

* refactored DocV and EnhancedDocV

* refactored BiometricKYC

* Update LocalStorage.swift

* remove whitespaces

* Update SelfieViewModel.swift

* added encryption and create prepupload and authentication file

* refactored save offline job

* fixed return statement

* fixed selfie duplication and removed authtoken

* fixed pr comments

* Added File Manager Helpers (#148)

* reworked file creation logic

* added create info.json file

* made create file more abstract

* removed whitespace

* updated info.json

* refactored DocV and EnhancedDocV

* refactored BiometricKYC

* Update LocalStorage.swift

* remove whitespaces

* Update SelfieViewModel.swift

* added encryption and create prepupload and authentication file

* refactored save offline job

* fixed return statement

* fixed selfie duplication and removed authtoken

* added file manager helper files

* fixed pr comments

* fixed merge conflicts

* Update IdInfo in BiometricKYC (#152)

* added update IdInfo in BiometricKYC

* Update UploadRequest.swift

* Prepare v10.0.10 release

* Update Changelog

---------

Co-authored-by: Vansh Gandhi <vansh@smileidentity.com>

* Move Files from Unsubmitted to Submitted Directories (#149)

* reworked file creation logic

* added create info.json file

* made create file more abstract

* removed whitespace

* updated info.json

* refactored DocV and EnhancedDocV

* refactored BiometricKYC

* Update LocalStorage.swift

* remove whitespaces

* Update SelfieViewModel.swift

* added encryption and create prepupload and authentication file

* refactored save offline job

* fixed return statement

* fixed selfie duplication and removed authtoken

* added file manager helper files

* move files from unsubmitted to submitted

* Update Podfile.lock

* updated move from unsubmitted to submitted directories

* fixed pr comments

* update error response

* Upload Offline Jobs (#151)

* reworked file creation logic

* made create file more abstract

* removed whitespace

* updated info.json

* move files from unsubmitted to submitted

* Update Podfile.lock

* updated move from unsubmitted to submitted directories

* added upload offline jobs

* removed jobStatusResponse

* updated jobStatusResponse on docv

* reworked offline mode submission

* added pr comment

* fixed PR comments

* Update IdInfo in BiometricKYC (#152)

* added update IdInfo in BiometricKYC

* Update UploadRequest.swift

* Prepare v10.0.10 release

* Update Changelog

---------

Co-authored-by: Vansh Gandhi <vansh@smileidentity.com>

* refactored BiometricKYC

* move files from unsubmitted to submitted

* Update Podfile.lock

* Reworked Local Storage  (#147)

* reworked file creation logic

* added create info.json file

* made create file more abstract

* removed whitespace

* updated info.json

* refactored DocV and EnhancedDocV

* refactored BiometricKYC

* Update LocalStorage.swift

* remove whitespaces

* Update SelfieViewModel.swift

* added encryption and create prepupload and authentication file

* refactored save offline job

* fixed return statement

* fixed selfie duplication and removed authtoken

* fixed pr comments

* added upload offline jobs

* removed jobStatusResponse

* reworked offline mode submission

* fixed PR comments

* rebased and fixed pr comments

* remove redeclared funcs

* updated offline mode config

* added submitJob utility function

* refactored image file types

* rebase with feat/offline epic

* rebase changelog and versions

* cleaning up

* fixed jsonDecoder

* fixed pr comments

* cleaning up  allFiles to be a let instead of var

* Fixed PR comments and cleaned up submitJob

* fixed offline upload

* Update OrchestratedBiometricKycViewModel.swift

* remove test data

* fixed move to submitted on http error

* catch non smile id errors

---------

Co-authored-by: Vansh Gandhi <vansh@smileidentity.com>

* Update Offline Message in Orchestrated Screens in Offline State (#161)

* updated offline message

* added error message on error state

* feat: swiftformat

* disable open brace lint warning

---------

Co-authored-by: JNdhlovu <jndhlovu54@gmail.com>

* rebase with main

* prepare for release

---------

Co-authored-by: Vansh Gandhi <vansh@smileidentity.com>
Co-authored-by: JNdhlovu <jndhlovu54@gmail.com>
  • Loading branch information
3 people authored May 8, 2024
1 parent 224407a commit a1b487f
Show file tree
Hide file tree
Showing 24 changed files with 713 additions and 417 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Release Notes

## 10.1.1

#### Added

* Added an Offline Mode, enabled by calling `SmileID.setAllowOfflineMode(true)`. If a job is attempted while the device is offline, and offline mode has been enabled, the UI will complete successfully and the job can be submitted at a later time by calling `SmileID.submitJob(jobId)`

## 10.1.0
* Add PrivacyInfo Manifest
* Added polling extensions for products
* Added an Offline Mode, enabled by calling `SmileID.setAllowOfflineMode(true)`. If a job is attempted while the device is offline, and offline mode has been enabled, the UI will complete successfully and the job can be submitted at a later time by calling `SmileID.submitJob(jobId)`

## 10.0.11

#### Fixed
* PartnerParams extras fixed to be in the correct format for the requests
* PartnerParams extras fixed to cater for the Photo param used in sandbox testing


## 10.0.10
* Set `IdInfo.entered` to true for Biometric KYC Jobs

Expand Down Expand Up @@ -233,4 +237,3 @@
#### Dependencies

* Zip

24 changes: 10 additions & 14 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
PODS:
- lottie-ios (4.4.2)
- netfox (1.21.0)
- Sentry (8.21.0):
- Sentry/Core (= 8.21.0)
- SentryPrivate (= 8.21.0)
- Sentry/Core (8.21.0):
- SentryPrivate (= 8.21.0)
- SentryPrivate (8.21.0)
- SmileID (10.1.0):
- lottie-ios (~> 4.4.2)
- Sentry (8.20.0):
- Sentry/Core (= 8.20.0)
- SentryPrivate (= 8.20.0)
- Sentry/Core (8.20.0):
- SentryPrivate (= 8.20.0)
- SentryPrivate (8.20.0)
- SmileID (10.0.10):
- Zip (~> 2.1.0)
- SwiftLint (0.54.0)
- Zip (2.1.2)
Expand All @@ -21,7 +19,6 @@ DEPENDENCIES:

SPEC REPOS:
trunk:
- lottie-ios
- netfox
- Sentry
- SentryPrivate
Expand All @@ -33,11 +30,10 @@ EXTERNAL SOURCES:
:path: "../"

SPEC CHECKSUMS:
lottie-ios: 4445b0bdb583c7a5325529f62246d311ee85fcd0
netfox: 9d5cc727fe7576c4c7688a2504618a156b7d44b7
Sentry: ebc12276bd17613a114ab359074096b6b3725203
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
SmileID: fa0d8d8738afc21fae721d398379020639d1e964
Sentry: a8d7b373b9f9868442b02a0c425192f693103cbf
SentryPrivate: 006b24af16828441f70e2ab6adf241bd0a8ad130
SmileID: ffaa1eab202cb9c402ade1cc66ceaf5a2c99c686
SwiftLint: c1de071d9d08c8aba837545f6254315bc900e211
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67

Expand Down
6 changes: 2 additions & 4 deletions Example/SmileID.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
620F1E982B69194900185CD2 /* AlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 620F1E972B69194900185CD2 /* AlertView.swift */; };
620F1E9A2B691ABB00185CD2 /* (null) in Resources */ = {isa = PBXBuildFile; };
620F1E9A2B691ABB00185CD2 /* BuildFile in Resources */ = {isa = PBXBuildFile; };
624777D02B0CDC9F00952842 /* EnhancedKycWithIdInputScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 624777CF2B0CDC9F00952842 /* EnhancedKycWithIdInputScreen.swift */; };
62F6766F2B0D173600417419 /* EnhancedKycWithIdInputScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62F6766E2B0D173600417419 /* EnhancedKycWithIdInputScreenViewModel.swift */; };
62F676712B0E00E800417419 /* EnhancedKycResultDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62F676702B0E00E800417419 /* EnhancedKycResultDelegate.swift */; };
Expand Down Expand Up @@ -436,7 +436,7 @@
buildActionMask = 2147483647;
files = (
1EFAB3172A375265008E3C13 /* Images.xcassets in Resources */,
620F1E9A2B691ABB00185CD2 /* (null) in Resources */,
620F1E9A2B691ABB00185CD2 /* BuildFile in Resources */,
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
5829A8C02BC7429A001C1E7E /* PrivacyInfo.xcprivacy in Resources */,
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
Expand Down Expand Up @@ -464,7 +464,6 @@
"${BUILT_PRODUCTS_DIR}/SentryPrivate/SentryPrivate.framework",
"${BUILT_PRODUCTS_DIR}/SmileID/SmileID.framework",
"${BUILT_PRODUCTS_DIR}/Zip/Zip.framework",
"${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework",
"${BUILT_PRODUCTS_DIR}/netfox/netfox.framework",
);
name = "[CP] Embed Pods Frameworks";
Expand All @@ -473,7 +472,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SentryPrivate.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SmileID.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Zip.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/netfox.framework",
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
8 changes: 4 additions & 4 deletions Example/SmileID/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct HomeView: View {
Text("Test Our Products")
.font(SmileID.theme.header2)
.foregroundColor(.black)

MyVerticalGrid(
maxColumns: 2,
items: [
Expand Down Expand Up @@ -124,16 +124,16 @@ struct SmartSelfieEnrollmentDelegate: SmartSelfieResultDelegate {
_ userId: String,
_ selfieFile: URL,
_ livenessImages: [URL],
_ jobStatusResponse: SmartSelfieJobStatusResponse?
_ didSubmitSmartSelfieJob: Bool
) -> Void
let onError: (Error) -> Void

func didSucceed(
selfieImage: URL,
livenessImages: [URL],
jobStatusResponse: SmartSelfieJobStatusResponse?
didSubmitSmartSelfieJob: Bool
) {
onEnrollmentSuccess(userId, selfieImage, livenessImages, jobStatusResponse)
onEnrollmentSuccess(userId, selfieImage, livenessImages, didSubmitSmartSelfieJob)
}

func didError(error: Error) {
Expand Down
2 changes: 1 addition & 1 deletion Example/SmileID/HomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class HomeViewController: UIViewController, SmartSelfieResultDelegate {
func didSucceed(
selfieImage: URL,
livenessImages: [URL],
jobStatusResponse: JobStatusResponse<SmartSelfieJobResult>?
didSubmitSmartSelfieJob: Bool
) {
cameraVC?.dismiss(animated: true, completion: {
switch self.currentJob {
Expand Down
46 changes: 11 additions & 35 deletions Example/SmileID/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,14 @@ class HomeViewModel: ObservableObject,
userId: String,
selfieImage _: URL,
livenessImages _: [URL],
jobStatusResponse: JobStatusResponse<SmartSelfieJobResult>?
didSubmitJob: Bool
) {
dismissModal()
showToast = true
UIPasteboard.general.string = userId
toastMessage = jobResultMessageBuilder(
jobName: "SmartSelfie Enrollment",
jobComplete: jobStatusResponse?.jobComplete,
jobSuccess: jobStatusResponse?.jobSuccess,
code: jobStatusResponse?.code,
resultCode: jobStatusResponse?.result?.resultCode,
resultText: jobStatusResponse?.result?.resultText,
didSubmitJob: didSubmitJob,
suffix: "The User ID has been copied to your clipboard"
)
}
Expand All @@ -68,34 +64,26 @@ class HomeViewModel: ObservableObject,
func didSucceed(
selfieImage _: URL,
livenessImages _: [URL],
jobStatusResponse: JobStatusResponse<SmartSelfieJobResult>?
didSubmitSmartSelfieJob: Bool
) {
dismissModal()
showToast = true
toastMessage = jobResultMessageBuilder(
jobName: "SmartSelfie Authentication",
jobComplete: jobStatusResponse?.jobComplete,
jobSuccess: jobStatusResponse?.jobSuccess,
code: jobStatusResponse?.code,
resultCode: jobStatusResponse?.result?.resultCode,
resultText: jobStatusResponse?.result?.resultText
didSubmitJob: didSubmitSmartSelfieJob
)
}

func didSucceed(
selfieImage _: URL,
livenessImages _: [URL],
jobStatusResponse: JobStatusResponse<BiometricKycJobResult>
didSubmitBiometricJob: Bool
) {
dismissModal()
showToast = true
toastMessage = jobResultMessageBuilder(
jobName: "Biometric KYC",
jobComplete: jobStatusResponse.jobComplete,
jobSuccess: jobStatusResponse.jobSuccess,
code: jobStatusResponse.code,
resultCode: jobStatusResponse.result?.resultCode,
resultText: jobStatusResponse.result?.resultText
didSubmitJob: didSubmitBiometricJob
)
}

Expand All @@ -106,47 +94,35 @@ class HomeViewModel: ObservableObject,
showToast = true
toastMessage = jobResultMessageBuilder(
jobName: "Enhanced KYC",
jobComplete: true,
jobSuccess: true,
code: nil,
resultCode: enhancedKycResponse.resultCode,
resultText: enhancedKycResponse.resultText
didSubmitJob: true
)
}

func didSucceed(
selfie _: URL,
documentFrontImage _: URL,
documentBackImage _: URL?,
jobStatusResponse: JobStatusResponse<DocumentVerificationJobResult>
didSubmitDocumentVerificationJob: Bool
) {
dismissModal()
showToast = true
toastMessage = jobResultMessageBuilder(
jobName: "Document Verification",
jobComplete: jobStatusResponse.jobComplete,
jobSuccess: jobStatusResponse.jobSuccess,
code: jobStatusResponse.code,
resultCode: jobStatusResponse.result?.resultCode,
resultText: jobStatusResponse.result?.resultText
didSubmitJob: didSubmitDocumentVerificationJob
)
}

func didSucceed(
selfie _: URL,
documentFrontImage _: URL,
documentBackImage _: URL?,
jobStatusResponse: JobStatusResponse<EnhancedDocumentVerificationJobResult>
didSubmitEnhancedDocVJob: Bool
) {
dismissModal()
showToast = true
toastMessage = jobResultMessageBuilder(
jobName: "Enhanced Document Verification",
jobComplete: jobStatusResponse.jobComplete,
jobSuccess: jobStatusResponse.jobSuccess,
code: jobStatusResponse.code,
resultCode: jobStatusResponse.result?.resultCode,
resultText: jobStatusResponse.result?.resultText
didSubmitJob: didSubmitEnhancedDocVJob
)
}

Expand Down
18 changes: 4 additions & 14 deletions Example/SmileID/Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,14 @@ func openUrl(_ urlString: String) {

func jobResultMessageBuilder(
jobName: String,
jobComplete: Bool?,
jobSuccess: Bool?,
code: String?,
resultCode: String?,
resultText: String?,
didSubmitJob: Bool?,
suffix: String? = nil
) -> String {
var message = "\(jobName) "
if jobComplete == true {
if jobSuccess == true {
message += "completed successfully"
} else {
message += "completed unsuccessfully"
}
message +=
" (resultText=\(resultText ?? "null"), code=\(code ?? "null"), resultCode=\(resultCode ?? "null"))"
if didSubmitJob == true {
message += "completed successfully"
} else {
message += "still pending"
message += "saved offline"
}
if let suffix = suffix {
message += ". \(suffix)"
Expand Down
6 changes: 3 additions & 3 deletions SmileID.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = 'SmileID'
s.version = '10.1.0'
s.version = '10.1.1'
s.summary = 'The Official Smile Identity iOS SDK.'
s.homepage = 'https://docs.usesmileid.com/integration-options/mobile/ios-v10-beta'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Japhet' => 'japhet@usesmileid.com', 'Juma Allan' => 'juma@usesmileid.com', 'Vansh Gandhi' => 'vansh@usesmileid.com'}
s.source = { :git => "https://github.com/smileidentity/ios.git", :tag => "v10.1.0" }
s.source = { :git => "https://github.com/smileidentity/ios.git", :tag => "v10.1.1" }
s.ios.deployment_target = '13.0'
s.dependency 'Zip', '~> 2.1.0'
s.dependency 'lottie-ios', '~> 4.4.2'
Expand All @@ -14,4 +14,4 @@ Pod::Spec.new do |s|
s.resource_bundles = {
'SmileID_SmileID' => ['Sources/SmileID/Resources/**/*.{storyboard,storyboardc,xib,nib,xcassets,json,png,ttf,lproj,xcprivacy}']
}
end
end
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
/// The result of a selfie capture session and Biometric KYC job submission. The Job itself may
/// or may not be complete yet. This can be checked with `jobStatusResponse.jobComplete`. If not
/// yet complete, the job status will need to be fetched again later. If the job is complete, the
/// final job success can be checked with `jobStatusResponse.jobSuccess`.

import Foundation

/// The result of a selfie capture session and Biometric KYC job submission.
public protocol BiometricKycResultDelegate {
/// This function is called as a result of a successful selfie capture and job submission
/// - Parameters:
/// - selfieImage: The local url of the colour selfie image captured
/// - livenessImages: An array of local urls of images captured for liveness checks
/// - jobStatusResponse: The response object after submitting the jib
/// - didSubmitBiometricJob: Indicates whether the job was submitted to the SmileID backend (e.g. it would be false in offline mode)
func didSucceed(
selfieImage: URL,
livenessImages: [URL],
jobStatusResponse: BiometricKycJobStatusResponse
didSubmitBiometricJob: Bool
)

/// An error occurred during the selfie capture session or job submission
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ struct OrchestratedBiometricKycScreen: View {
skipApiSubmission: true,
onResult: viewModel
)
case .processing(let state):
case let .processing(state):
ProcessingScreen(
processingState: state,
inProgressTitle: SmileIDResourcesHelper.localizedString(
Expand All @@ -68,12 +68,12 @@ struct OrchestratedBiometricKycScreen: View {
for: "BiometricKYC.Success.Title"
),
successSubtitle: SmileIDResourcesHelper.localizedString(
for: "BiometricKYC.Success.Subtitle"
for: $viewModel.errorMessage.wrappedValue ?? "BiometricKYC.Success.Subtitle"
),
successIcon: SmileIDResourcesHelper.CheckBold,
errorTitle: SmileIDResourcesHelper.localizedString(for: "BiometricKYC.Error.Title"),
errorSubtitle: SmileIDResourcesHelper.localizedString(
for: "BiometricKYC.Error.Subtitle"
for: $viewModel.errorMessage.wrappedValue ?? "BiometricKYC.Error.Subtitle"
),
errorIcon: SmileIDResourcesHelper.Scan,
continueButtonText: SmileIDResourcesHelper.localizedString(
Expand Down
Loading

0 comments on commit a1b487f

Please sign in to comment.