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

feat: make polling to par with android #211

Merged
merged 11 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ archives
*.mobileprovision
*.sentryclirc
.sentryclirc
**/ArkanaKeys/

# JetBrains/AppCode
.idea
Expand Down
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ We use [`rake`](https://github.com/ruby/rake) for task automation.
- iOS 13 or higher
- Xcode 14 or higher

## Sentry setup (Sample app only)

```shell
export SENTRY_DSN='your_sentry_dsn'
```
Run the following command to install the required variable for use in the example app

```shell
bundle exec arkana -c .arkana.yml -l swift
```
bundle exec rake test:package

## SDK Tests

```shell
Expand Down
3 changes: 3 additions & 0 deletions Example/.arkana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
global_secrets:
- SENTRY_DSN
package_manager: cocoapods
2 changes: 2 additions & 0 deletions Example/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ target 'SmileID_Example' do
pod 'netfox'
pod 'Sentry'
pod 'SwiftLint'
pod 'ArkanaKeys', :path => './ArkanaKeys/ArkanaKeys/'
pod 'ArkanaKeysInterfaces', :path => './ArkanaKeys/ArkanaKeysInterfaces/'

target 'SmileID_Tests' do
inherit! :search_paths
Expand Down
13 changes: 12 additions & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
PODS:
- ArkanaKeys (1.0.0):
- ArkanaKeysInterfaces (~> 1.0.0)
- ArkanaKeysInterfaces (1.0.0)
- lottie-ios (4.4.3)
- netfox (1.21.0)
- Sentry (8.31.1):
Expand All @@ -11,6 +14,8 @@ PODS:
- Zip (2.1.2)

DEPENDENCIES:
- ArkanaKeys (from `./ArkanaKeys/ArkanaKeys/`)
- ArkanaKeysInterfaces (from `./ArkanaKeys/ArkanaKeysInterfaces/`)
- netfox
- Sentry
- SmileID (from `../`)
Expand All @@ -25,17 +30,23 @@ SPEC REPOS:
- Zip

EXTERNAL SOURCES:
ArkanaKeys:
:path: "./ArkanaKeys/ArkanaKeys/"
ArkanaKeysInterfaces:
:path: "./ArkanaKeys/ArkanaKeysInterfaces/"
SmileID:
:path: "../"

SPEC CHECKSUMS:
ArkanaKeys: 356555f467c55ae40ba074c1b4d9cb5c38a55f3d
ArkanaKeysInterfaces: 81d21923368b058e2b6fd932ec96855166ef6d19
lottie-ios: fcb5e73e17ba4c983140b7d21095c834b3087418
netfox: 9d5cc727fe7576c4c7688a2504618a156b7d44b7
Sentry: 9c1188876ea1291d1a9db4b38c3f17ebd8e6985e
SmileID: 09d42fdc65cd4d2b0d33fd33e14e8c85a189a64b
SwiftLint: 3fe909719babe5537c552ee8181c0031392be933
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67

PODFILE CHECKSUM: 8f7be2cf75babf479684f1e21d344f4c640486be
PODFILE CHECKSUM: ebb96bfc1b5a0c7f6061ff1e91ac138e67c1d9f4

COCOAPODS: 1.15.2
8 changes: 6 additions & 2 deletions Example/SmileID.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@
"${BUILT_PRODUCTS_DIR}/Zip/Zip.framework",
"${BUILT_PRODUCTS_DIR}/lottie-ios/Lottie.framework",
"${BUILT_PRODUCTS_DIR}/netfox/netfox.framework",
"${BUILT_PRODUCTS_DIR}/ArkanaKeys/ArkanaKeys.framework",
"${BUILT_PRODUCTS_DIR}/ArkanaKeysInterfaces/ArkanaKeysInterfaces.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
Expand All @@ -583,6 +585,8 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Zip.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lottie.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/netfox.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ArkanaKeys.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ArkanaKeysInterfaces.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
Expand Down Expand Up @@ -896,7 +900,7 @@
PRODUCT_NAME = "Smile ID";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.smileidentity.example-ios";
SENTRY_DSN = "$(SENTRY_DSN)";
ENABLE_SENTRY = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
Expand Down Expand Up @@ -929,7 +933,7 @@
PRODUCT_NAME = "Smile ID";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.smileidentity.example-ios";
SENTRY_DSN = "$(SENTRY_DSN)";
ENABLE_SENTRY = NO;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
Expand Down
12 changes: 10 additions & 2 deletions Example/SmileID/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Sentry
import SmileID
import SwiftUI
import UIKit
import ArkanaKeys

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -15,9 +16,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
UINavigationBar.appearance().titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.black
]
if let dsn = Bundle.main.object(forInfoDictionaryKey: "SentryDSN") as? String {
if(enableSentry()){
SentrySDK.start { options in
options.dsn = dsn
options.dsn = ArkanaKeys.Global().sENTRY_DSN
options.debug = true
options.tracesSampleRate = 1.0
options.profilesSampleRate = 1.0
Expand All @@ -31,4 +32,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window?.makeKeyAndVisible()
return true
}

func enableSentry() -> Bool {
guard let enableSentry = Bundle.main.object(forInfoDictionaryKey: "EnableSentry") as? String else {
return false
}
return enableSentry == "YES"
}
}
4 changes: 2 additions & 2 deletions Example/SmileID/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
<string>We need access to your camera to verify your identity </string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to save images</string>
<key>SentryDSN</key>
<string>$(SENTRY_DSN)</string>
<key>EnableSentry</key>
<string>$(ENABLE_SENTRY)</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand Down
22 changes: 13 additions & 9 deletions Example/SmileID/Jobs/JobItemModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,30 @@ class JobItemModel: ObservableObject {
timestamp: authResponse.timestamp,
signature: authResponse.signature
)

let response = try await SmileID.api.pollJobStatus(
let pollStream = SmileID.api.pollJobStatus(
request: request,
interval: 1,
numAttempts: 30
)
var response : JobStatusResponse<JobResult>? = nil
Copy link

@github-actions github-actions bot Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • ⚠️ Initializing an optional variable with nil is redundant. (redundant_optional_initialization)


for try await res in pollStream {
response = res
}

return JobData(
jobType: job.jobType,
timestamp: job.timestamp,
userId: job.userId,
jobId: job.jobId,
partnerId: job.partnerId,
jobComplete: response.jobComplete,
jobSuccess: response.jobSuccess,
code: response.code,
resultCode: response.result?.resultCode,
smileJobId: response.result?.smileJobId,
resultText: response.result?.resultText,
selfieImageUrl: response.imageLinks?.selfieImageUrl
jobComplete: response?.jobComplete ?? false,
jobSuccess: response?.jobSuccess ?? false,
code: response?.code,
resultCode: response?.result?.resultCode,
smileJobId: response?.result?.smileJobId,
resultText: response?.result?.resultText,
selfieImageUrl: response?.imageLinks?.selfieImageUrl
)
}

Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ source "https://rubygems.org"

gem "fastlane"
gem "xcodeproj"
gem "arkana"
gem 'cocoapods', '~> 1.11.0'
gem "rake", "~> 13.0.0"
9 changes: 8 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ GEM
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
arkana (2.1.1)
dotenv (~> 2.7)
rainbow (~> 3.1.1)
yaml (~> 0.2)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
Expand Down Expand Up @@ -220,6 +224,7 @@ GEM
os (1.1.4)
plist (3.7.0)
public_suffix (4.0.7)
rainbow (3.1.1)
rake (13.0.6)
representable (3.2.0)
declarative (< 0.1.0)
Expand Down Expand Up @@ -270,6 +275,7 @@ GEM
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
yaml (0.3.0)
zeitwerk (2.6.11)

PLATFORMS
Expand All @@ -278,10 +284,11 @@ PLATFORMS
x86_64-linux

DEPENDENCIES
arkana
cocoapods (~> 1.11.0)
fastlane
rake (~> 13.0.0)
xcodeproj

BUNDLED WITH
2.3.11
2.5.6
60 changes: 29 additions & 31 deletions Sources/SmileID/Classes/Networking/SmileIDService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,35 +97,33 @@ public extension SmileIDServiceable {
/// - numAttempts: The maximum number of polls before ending the flow
func pollJobStatus<T: JobResult>(
request: JobStatusRequest,
interval _: TimeInterval,
interval: TimeInterval,
numAttempts: Int
) async throws -> JobStatusResponse<T> {
var lastError: Error?
var attemptCount = 0

func makeRequest() async throws -> JobStatusResponse<T> {
attemptCount += 1

do {
let response: JobStatusResponse<T> = try await SmileID.api.getJobStatus(request: request)
if response.jobComplete {
return response
} else if attemptCount < numAttempts {
return try await makeRequest()
} else {
throw SmileIDError.jobStatusTimeOut
) -> AsyncThrowingStream<JobStatusResponse<T>, Error> {
AsyncThrowingStream { continuation in
Task {
var latestError: Error?
for _ in 0..<numAttempts {
do {
let response: JobStatusResponse<T> = try await SmileID.api.getJobStatus(request: request)
continuation.yield(response)
// Reset the error if the API response was successful
latestError = nil
if response.jobComplete {
break
}
} catch {
latestError = error
}
try await Task.sleep(nanoseconds: UInt64(interval * 1_000_000_000))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain why you're introducing this delay? I think this can slow down the code execution.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already discussed this during our sync.

}
} catch {
lastError = error
if attemptCount < numAttempts {
return try await makeRequest()
if let latestError = latestError {
continuation.finish(throwing: latestError)
} else {
throw lastError ?? error
continuation.finish()
}
}
}

return try await makeRequest()
}

/// Polls the server for the status of a SmartSelfie Job until it is complete. This should be called after
Expand All @@ -141,8 +139,8 @@ public extension SmileIDServiceable {
request: JobStatusRequest,
interval: TimeInterval,
numAttempts: Int
) async throws -> SmartSelfieJobStatusResponse {
try await pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
) async throws -> AsyncThrowingStream<SmartSelfieJobStatusResponse, Error> {
return pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
}

/// Polls the server for the status of a Document Verification Job until it is complete. This should be called after
Expand All @@ -158,8 +156,8 @@ public extension SmileIDServiceable {
request: JobStatusRequest,
interval: TimeInterval,
numAttempts: Int
) async throws -> DocumentVerificationJobStatusResponse {
try await pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
) async throws -> AsyncThrowingStream<DocumentVerificationJobStatusResponse, Error> {
return pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
}

/// Polls the server for the status of a Biometric KYC Job until it is complete. This should be called after
Expand All @@ -175,8 +173,8 @@ public extension SmileIDServiceable {
request: JobStatusRequest,
interval: TimeInterval,
numAttempts: Int
) async throws -> BiometricKycJobStatusResponse {
try await pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
) async throws -> AsyncThrowingStream<BiometricKycJobStatusResponse, Error> {
return pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
}

/// Polls the server for the status of a Enhanced Document Verification Job until it is complete.
Expand All @@ -193,8 +191,8 @@ public extension SmileIDServiceable {
request: JobStatusRequest,
interval: TimeInterval,
numAttempts: Int
) async throws -> EnhancedDocumentVerificationJobStatusResponse {
try await pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
) async throws -> AsyncThrowingStream<EnhancedDocumentVerificationJobStatusResponse, Error> {
return pollJobStatus(request: request, interval: interval, numAttempts: numAttempts)
}
}

Expand Down
Loading
Loading