Skip to content

Commit

Permalink
Merge branch 'main' into jobs-list-screen
Browse files Browse the repository at this point in the history
  • Loading branch information
tobitech committed Jul 15, 2024
2 parents 2b80e2c + 6c4fcf3 commit 8732a76
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 19 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# Release Notes
## 10.2.2

#### Fixed
* Remove force unwrapping for getting files from storage

## 10.2.1

#### Added
* Handle unauthorized camera status

## 10.2.0

Expand Down
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ PODS:
- Sentry (8.26.0):
- Sentry/Core (= 8.26.0)
- Sentry/Core (8.26.0)
- SmileID (10.2.0):
- SmileID (10.2.2):
- lottie-ios (~> 4.4.2)
- Zip (~> 2.1.0)
- SwiftLint (0.55.1)
Expand Down Expand Up @@ -32,7 +32,7 @@ SPEC CHECKSUMS:
lottie-ios: fcb5e73e17ba4c983140b7d21095c834b3087418
netfox: 9d5cc727fe7576c4c7688a2504618a156b7d44b7
Sentry: 74a073c71c998117edb08f56f443c83570a31bed
SmileID: bfcd426e9a47560eb949c18591ad032a8d8cde0d
SmileID: 9d95463475f933422b2ce136474813b528dbedb7
SwiftLint: 3fe909719babe5537c552ee8181c0031392be933
Zip: b3fef584b147b6e582b2256a9815c897d60ddc67

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
4 changes: 2 additions & 2 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.2.0'
s.version = '10.2.2'
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.2.0" }
s.source = { :git => "https://github.com/smileidentity/ios.git", :tag => "v10.2.2" }
s.ios.deployment_target = '13.0'
s.dependency 'Zip', '~> 2.1.0'
s.dependency 'lottie-ios', '~> 4.4.2'
Expand Down
3 changes: 2 additions & 1 deletion Sources/SmileID/Classes/Camera/CameraManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CameraManager: NSObject, ObservableObject {
private let sessionQueue = DispatchQueue(label: "com.smileidentity.ios")
private let videoOutput = AVCaptureVideoDataOutput()
private let photoOutput = AVCapturePhotoOutput()
private var status = Status.unconfigured
@Published private(set) var status = Status.unconfigured
private var orientation: Orientation

init(orientation: Orientation) {
Expand All @@ -48,6 +48,7 @@ class CameraManager: NSObject, ObservableObject {
sessionQueue.async {
self.videoOutput.setSampleBufferDelegate(self, queue: self.videoOutputQueue)
}
checkPermissions()
}

private func set(error: CameraError?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ class DocumentCaptureViewModel: ObservableObject {
// Other properties
private let defaultAspectRatio: Double
private let textDetector = TextDetector()
private var imageCaptureSubscriber: AnyCancellable?
private var cameraBufferSubscriber: AnyCancellable?
private var subscribers = Set<AnyCancellable>()
private var processingImage = false
private var documentFirstDetectedAtTime: TimeInterval?
private var lastAnalysisTime: TimeInterval = 0
private var areEdgesDetectedSubscriber: AnyCancellable?

// UI properties
@Published var unauthorizedAlert: AlertState?
@Published var acknowledgedInstructions = false
@Published var showPhotoPicker = false
@Published var directive: DocumentDirective = .defaultInstructions
Expand All @@ -44,15 +44,24 @@ class DocumentCaptureViewModel: ObservableObject {
idAspectRatio = defaultAspectRatio
}

imageCaptureSubscriber = cameraManager.capturedImagePublisher
cameraManager.$status
.receive(on: DispatchQueue.main)
.filter { $0 == .unauthorized }
.map { _ in AlertState.cameraUnauthorized }
.sink { alert in self.unauthorizedAlert = alert }
.store(in: &subscribers)

cameraManager.capturedImagePublisher
.receive(on: DispatchQueue.global())
.compactMap { $0 }
.sink(receiveValue: onCaptureComplete)
.store(in: &subscribers)

cameraBufferSubscriber = cameraManager.sampleBufferPublisher
cameraManager.sampleBufferPublisher
.receive(on: DispatchQueue(label: "com.smileidentity.receivebuffer"))
.compactMap { $0 }
.sink(receiveValue: analyzeImage)
.store(in: &subscribers)

// Show Manual Capture button after 10 seconds
Timer.scheduledTimer(
Expand Down Expand Up @@ -248,4 +257,9 @@ class DocumentCaptureViewModel: ObservableObject {

return isCenteredHorizontally && isCenteredVertically
}

func openSettings() {
guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(settingsURL)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ public struct DocumentCaptureScreen: View {
cameraManager: viewModel.cameraManager,
onCaptureClick: viewModel.captureDocument
)
.alert(item: $viewModel.unauthorizedAlert) { alert in
Alert(
title: Text(alert.title),
message: Text(alert.message ?? ""),
primaryButton: .default(
Text(SmileIDResourcesHelper.localizedString(for: "Camera.Unauthorized.PrimaryAction")),
action: {
viewModel.openSettings()
}
),
secondaryButton: .cancel()
)
}
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions Sources/SmileID/Classes/Helpers/AlertState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation

/// A type representing the state necessary to display a native iOS alert.
struct AlertState: Identifiable {
let id: UUID
let title: String
let message: String?

init(
id: UUID = UUID(),
title: String,
message: String? = nil
) {
self.id = id
self.title = title
self.message = message
}
}

extension AlertState {
/// A static property representing an alert state for unauthorized camera access.
static var cameraUnauthorized: Self {
AlertState(
title: SmileIDResourcesHelper.localizedString(for: "Camera.Unauthorized.Title"),
message: SmileIDResourcesHelper.localizedString(for: "Camera.Unauthorized.Message")
)
}
}
2 changes: 1 addition & 1 deletion Sources/SmileID/Classes/Helpers/LocalStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class LocalStorage {
submitted: Bool = false
) throws -> URL? {
let contents = try getDirectoryContents(jobId: jobId, submitted: submitted)
return contents.first(where: { $0.lastPathComponent.contains(fileType.name) })!
return contents.first(where: { $0.lastPathComponent.contains(fileType.name) })
}

static func getFilesByType(
Expand Down
14 changes: 14 additions & 0 deletions Sources/SmileID/Classes/SelfieCapture/SelfieViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class SelfieViewModel: ObservableObject, ARKitSmileDelegate {
private var subscribers = Set<AnyCancellable>()

// UI Properties
@Published var unauthorizedAlert: AlertState?
@Published var directive: String = "Instructions.Start"
/// we use `errorMessageRes` to map to the actual code to the stringRes to allow localization,
/// and use `errorMessage` to show the actual platform error message that we show if
Expand Down Expand Up @@ -72,6 +73,14 @@ public class SelfieViewModel: ObservableObject, ARKitSmileDelegate {
self.allowNewEnroll = allowNewEnroll
self.skipApiSubmission = skipApiSubmission
self.extraPartnerParams = extraPartnerParams

cameraManager.$status
.receive(on: DispatchQueue.main)
.filter { $0 == .unauthorized }
.map { _ in AlertState.cameraUnauthorized }
.sink { alert in self.unauthorizedAlert = alert }
.store(in: &subscribers)

cameraManager.sampleBufferPublisher
.merge(with: arKitFramePublisher)
.throttle(for: 0.35, scheduler: DispatchQueue.global(qos: .userInitiated), latest: true)
Expand Down Expand Up @@ -436,4 +445,9 @@ public class SelfieViewModel: ObservableObject, ARKitSmileDelegate {
callback.didError(error: SmileIDError.unknown("Unknown error"))
}
}

func openSettings() {
guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(settingsURL)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,18 @@ public struct SelfieCaptureScreen: View {
}
.padding(24)
}
.alert(item: $viewModel.unauthorizedAlert) { alert in
Alert(
title: Text(alert.title),
message: Text(alert.message ?? ""),
primaryButton: .default(
Text(SmileIDResourcesHelper.localizedString(for: "Camera.Unauthorized.PrimaryAction")),
action: {
viewModel.openSettings()
}
),
secondaryButton: .cancel()
)
}
}
}
21 changes: 14 additions & 7 deletions Sources/SmileID/Classes/SmileID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SwiftUI
import UIKit

public class SmileID {
public static let version = "10.2.0"
public static let version = "10.2.2"
@Injected var injectedApi: SmileIDServiceable
public static var configuration: Config { config }

Expand Down Expand Up @@ -148,12 +148,19 @@ public class SmileID {
signature: authResponse.signature
)
let prepUploadResponse = try await SmileID.api.prepUpload(request: prepUploadRequest)
let allFiles = try LocalStorage.getFilesByType(jobId: jobId, fileType: FileType.liveness)! + [
LocalStorage.getFileByType(jobId: jobId, fileType: FileType.selfie),
LocalStorage.getFileByType(jobId: jobId, fileType: FileType.documentFront),
LocalStorage.getFileByType(jobId: jobId, fileType: FileType.documentBack),
LocalStorage.getInfoJsonFile(jobId: jobId)
].compactMap { $0 }
let allFiles: [URL]
do {
let livenessFiles = try LocalStorage.getFilesByType(jobId: jobId, fileType: .liveness) ?? []
let additionalFiles = try [
LocalStorage.getFileByType(jobId: jobId, fileType: .selfie),
LocalStorage.getFileByType(jobId: jobId, fileType: .documentFront),
LocalStorage.getFileByType(jobId: jobId, fileType: .documentBack),
LocalStorage.getInfoJsonFile(jobId: jobId)
].compactMap { $0 }
allFiles = livenessFiles + additionalFiles
} catch {
throw error
}
let zipUrl = try LocalStorage.zipFiles(at: allFiles)
zip = try Data(contentsOf: zipUrl)
_ = try await SmileID.api.upload(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"Action.Skip" = "Skip back of ID";

"Camera.AgentMode" = "Agent Mode";
"Camera.Unauthorized.Title" = "Allow access to your camera";
"Camera.Unauthorized.Message" = "The camera permission is required to complete the verification process.";
"Camera.Unauthorized.PrimaryAction" = "Open Settings";

"Document.Confirmation.Header" = "Is the document clear and readable?";
"Document.Confirmation.Callout" = "Make sure all corners of the document are visible and there is no glare";
Expand Down

0 comments on commit 8732a76

Please sign in to comment.